Skip to content

Commit

Permalink
Fixed bug #70430
Browse files Browse the repository at this point in the history
  • Loading branch information
nikic committed Oct 15, 2015
1 parent 06f38d3 commit e3e92e9
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 10 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ PHP NEWS

- Core:
. Fixed bug #70689 (Exception handler does not work as expected). (Laruence)
. Fixed bug #70430 (Stack buffer overflow in zend_language_parser()). (Nikita)

- SOAP:
. Fixed bug #70715 (Segmentation fault inside soap client). (Laruence)
Expand Down
10 changes: 10 additions & 0 deletions Zend/tests/bug70430.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--TEST--
Bug #70430: Stack buffer overflow in zend_language_parser()
--FILE--
<?php

$"*** Testing function() : ***\n";

?>
--EXPECTF--
Parse error: syntax error, unexpected '"*** Testing function() : ***' (T_CONSTANT_ENCAPSED_STRING), expecting variable (T_VARIABLE) or '{' or '$' in %s on line %d
38 changes: 28 additions & 10 deletions Zend/zend_language_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -1278,20 +1278,30 @@ isset_variable:
would have been. */
static YYSIZE_T zend_yytnamerr(char *yyres, const char *yystr)
{
if (!yyres) {
return yystrlen(yystr);
/* CG(parse_error) states:
* 0 => yyres = NULL, yystr is the unexpected token
* 1 => yyres = NULL, yystr is one of the expected tokens
* 2 => yyres != NULL, yystr is the unexpected token
* 3 => yyres != NULL, yystr is one of the expected tokens
*/
if (yyres && CG(parse_error) < 2) {
CG(parse_error) = 2;
}
if (CG(parse_error) == 0) {

if (CG(parse_error) % 2 == 0) {
/* The unexpected token */
char buffer[120];
const unsigned char *end, *str, *tok1 = NULL, *tok2 = NULL;
unsigned int len = 0, toklen = 0, yystr_len;

CG(parse_error) = 1;
CG(parse_error)++;

if (LANG_SCNG(yy_text)[0] == 0 &&
LANG_SCNG(yy_leng) == 1 &&
memcmp(yystr, "\"end of file\"", sizeof("\"end of file\"") - 1) == 0) {
yystpcpy(yyres, "end of file");
if (yyres) {
yystpcpy(yyres, "end of file");
}
return sizeof("end of file")-1;
}

Expand All @@ -1312,14 +1322,22 @@ static YYSIZE_T zend_yytnamerr(char *yyres, const char *yystr)
} else {
len = (end - str) > 30 ? 30 : (end - str);
}
if (toklen) {
snprintf(buffer, sizeof(buffer), "'%.*s' %.*s", len, str, toklen, tok1);
} else {
snprintf(buffer, sizeof(buffer), "'%.*s'", len, str);
if (yyres) {
if (toklen) {
snprintf(buffer, sizeof(buffer), "'%.*s' %.*s", len, str, toklen, tok1);
} else {
snprintf(buffer, sizeof(buffer), "'%.*s'", len, str);
}
yystpcpy(yyres, buffer);
}
yystpcpy(yyres, buffer);
return len + (toklen ? toklen + 1 : 0) + 2;
}

/* One of the expected tokens */
if (!yyres) {
return yystrlen(yystr) - (*yystr == '"' ? 2 : 0);
}

if (*yystr == '"') {
YYSIZE_T yyn = 0;
const char *yyp = yystr;
Expand Down

0 comments on commit e3e92e9

Please sign in to comment.