diff options
| author | Nikita Popov <nikita.ppv@gmail.com> | 2019-10-04 22:42:14 +0200 |
|---|---|---|
| committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-10-04 22:42:14 +0200 |
| commit | 239e2dda6487761271fa5258e642b716dd79a02b (patch) | |
| tree | b7ca8728f68deda192f5b141c7c368ad2b31dffb /Zend/zend_language_scanner.l | |
| parent | 1d6e9da7433bddca5c591ef5b2eeef9c410543bb (diff) | |
| download | php-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.l | 15 |
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(¤t_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(¤t_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 |
