summaryrefslogtreecommitdiff
path: root/Zend/zend_language_scanner.l
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-10-04 22:42:14 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-10-04 22:42:14 +0200
commit239e2dda6487761271fa5258e642b716dd79a02b (patch)
treeb7ca8728f68deda192f5b141c7c368ad2b31dffb /Zend/zend_language_scanner.l
parent1d6e9da7433bddca5c591ef5b2eeef9c410543bb (diff)
downloadphp-git-239e2dda6487761271fa5258e642b716dd79a02b.tar.gz
Make sure T_ERROR is returned for all lexer exceptions
This originally manifested as a leak in oss-fuzz #18000. The following is a reduced test case: <?php [ 5 => 1, "foo" > 1, " " => "" == 0 ]; <<<BAR $x BAR; Because this particular error condition did not return T_ERROR, EG(exception) was set while performing binary operation constant evaluation, which checks exceptions for cast failures. Instead of adding this indirect test case, I'm adding an assertion that the lexer has to return T_ERROR if EG(exception) is set.
Diffstat (limited to 'Zend/zend_language_scanner.l')
-rw-r--r--Zend/zend_language_scanner.l15
1 files changed, 15 insertions, 0 deletions
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index 2b432abe54..704aa998d3 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -2323,6 +2323,9 @@ skip_escape_conversion:
if (!IS_LABEL_SUCCESSOR(YYCURSOR[heredoc_label->length])) {
if (spacing == (HEREDOC_USING_SPACES | HEREDOC_USING_TABS)) {
zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0);
+ if (PARSER_MODE()) {
+ RETURN_TOKEN(T_ERROR);
+ }
}
YYCURSOR = saved_cursor;
@@ -2339,6 +2342,7 @@ skip_escape_conversion:
zend_lex_state current_state;
int heredoc_nesting_level = 1;
int first_token = 0;
+ int error = 0;
zend_save_lexical_state(&current_state);
@@ -2386,6 +2390,7 @@ skip_escape_conversion:
|| first_token == T_CURLY_OPEN
) && SCNG(heredoc_indentation)) {
zend_throw_exception_ex(zend_ce_parse_error, 0, "Invalid body indentation level (expecting an indentation level of at least %d)", SCNG(heredoc_indentation));
+ error = 1;
}
heredoc_label->indentation = SCNG(heredoc_indentation);
@@ -2394,6 +2399,10 @@ skip_escape_conversion:
zend_restore_lexical_state(&current_state);
SCNG(heredoc_scan_ahead) = 0;
CG(increment_lineno) = 0;
+
+ if (PARSER_MODE() && error) {
+ RETURN_TOKEN(T_ERROR);
+ }
}
RETURN_TOKEN(T_START_HEREDOC);
@@ -2583,6 +2592,9 @@ double_quotes_scan_done:
if (spacing == (HEREDOC_USING_SPACES | HEREDOC_USING_TABS)) {
zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0);
+ if (PARSER_MODE()) {
+ RETURN_TOKEN(T_ERROR);
+ }
}
/* newline before label will be subtracted from returned text, but
@@ -2704,6 +2716,9 @@ heredoc_scan_done:
if (spacing == (HEREDOC_USING_SPACES | HEREDOC_USING_TABS)) {
zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0);
+ if (PARSER_MODE()) {
+ RETURN_TOKEN(T_ERROR);
+ }
}
/* newline before label will be subtracted from returned text, but