diff options
| author | Nikita Popov <nikita.ppv@gmail.com> | 2019-10-12 21:27:44 +0200 |
|---|---|---|
| committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-10-14 16:36:27 +0200 |
| commit | 641f9615cc81f2393504f569db51c02a19d26061 (patch) | |
| tree | 52fe0ef87493a743bef78982d374b0555f141866 | |
| parent | c518932c0326a938f0fd0254f2adb03b1cddfbca (diff) | |
| download | php-git-641f9615cc81f2393504f569db51c02a19d26061.tar.gz | |
Fix handling of overflowing invalid octal in tokenizer
If token_get_all() is used, we still need to correctly distinguish
LNUMBER vs DNUMBER here for backwards compatibility.
| -rw-r--r-- | Zend/tests/bug71086.phpt | 2 | ||||
| -rw-r--r-- | Zend/zend_language_scanner.l | 21 | ||||
| -rw-r--r-- | ext/tokenizer/tests/invalid_octal_dnumber.phpt | 8 |
3 files changed, 23 insertions, 8 deletions
diff --git a/Zend/tests/bug71086.phpt b/Zend/tests/bug71086.phpt index a7600c51fd..3e64f9c13a 100644 --- a/Zend/tests/bug71086.phpt +++ b/Zend/tests/bug71086.phpt @@ -9,6 +9,6 @@ var_dump($highlightedString); ?> --EXPECT-- string(169) "<code><span style="color: #000000"> -<span style="color: #0000BB"><?php <br /> </span><span style="color: #007700">09 09 09;</span> +<span style="color: #0000BB"><?php <br /> 09 09 09</span><span style="color: #007700">;</span> </span> </code>" diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index fbcdd2c9b6..7dcb4dfcee 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -1820,25 +1820,32 @@ NEWLINE ("\r"|"\n"|"\r\n") zend_bool is_octal = lnum[0] == '0'; zend_bool contains_underscores = (memchr(lnum, '_', len) != NULL); + if (contains_underscores) { + lnum = estrndup(lnum, len); + strip_underscores(lnum, &len); + } + /* Digits 8 and 9 are illegal in octal literals. */ if (is_octal) { size_t i; for (i = 0; i < len; i++) { if (lnum[i] == '8' || lnum[i] == '9') { zend_throw_exception(zend_ce_parse_error, "Invalid numeric literal", 0); - ZVAL_UNDEF(zendlval); if (PARSER_MODE()) { + if (contains_underscores) { + efree(lnum); + } + ZVAL_UNDEF(zendlval); RETURN_TOKEN(T_ERROR); } - RETURN_TOKEN_WITH_VAL(T_LNUMBER); + + /* Continue in order to determine if this is T_LNUMBER or T_DNUMBER. */ + len = i; + break; } } } - if (contains_underscores) { - lnum = estrndup(lnum, len); - strip_underscores(lnum, &len); - } if (len < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */ errno = 0; @@ -1850,7 +1857,7 @@ NEWLINE ("\r"|"\n"|"\r\n") ZVAL_LONG(zendlval, ZEND_STRTOL(lnum, &end, 0)); if (errno == ERANGE) { /* Overflow */ errno = 0; - if (lnum[0] == '0') { /* octal overflow */ + if (is_octal) { /* octal overflow */ ZVAL_DOUBLE(zendlval, zend_oct_strtod(lnum, (const char **)&end)); } else { ZVAL_DOUBLE(zendlval, zend_strtod(lnum, (const char **)&end)); diff --git a/ext/tokenizer/tests/invalid_octal_dnumber.phpt b/ext/tokenizer/tests/invalid_octal_dnumber.phpt new file mode 100644 index 0000000000..ebe2bc4bcd --- /dev/null +++ b/ext/tokenizer/tests/invalid_octal_dnumber.phpt @@ -0,0 +1,8 @@ +--TEST-- +Invalid octal number that overflows to double +--FILE-- +<?php +echo token_name(token_get_all('<?php 0177777777777777777777787')[1][0]), "\n"; +?> +--EXPECT-- +T_DNUMBER |
