summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-10-12 21:27:44 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-10-14 16:36:27 +0200
commit641f9615cc81f2393504f569db51c02a19d26061 (patch)
tree52fe0ef87493a743bef78982d374b0555f141866
parentc518932c0326a938f0fd0254f2adb03b1cddfbca (diff)
downloadphp-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.phpt2
-rw-r--r--Zend/zend_language_scanner.l21
-rw-r--r--ext/tokenizer/tests/invalid_octal_dnumber.phpt8
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">&lt;?php&nbsp;<br />&nbsp;</span><span style="color: #007700">09&nbsp;09&nbsp;09;</span>
+<span style="color: #0000BB">&lt;?php&nbsp;<br />&nbsp;09&nbsp;09&nbsp;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