diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 42681b97461b1..2ccdc8b011689 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -210,6 +210,7 @@ void shutdown_scanner(void) zend_ptr_stack_destroy(&SCNG(heredoc_label_stack)); SCNG(heredoc_scan_ahead) = 0; SCNG(on_event) = NULL; + SCNG(on_event_context) = NULL; } ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state) @@ -581,6 +582,8 @@ ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle) zend_set_compiled_filename(compiled_filename); zend_string_release_ex(compiled_filename, 0); + SCNG(on_event) = NULL; + SCNG(on_event_context) = NULL; RESET_DOC_COMMENT(); CG(zend_lineno) = 1; CG(increment_lineno) = 0; @@ -766,6 +769,8 @@ ZEND_API void zend_prepare_string_for_scanning(zval *str, zend_string *filename) zend_set_compiled_filename(filename); CG(zend_lineno) = 1; CG(increment_lineno) = 0; + SCNG(on_event) = NULL; + SCNG(on_event_context) = NULL; RESET_DOC_COMMENT(); } @@ -1636,6 +1641,9 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ "("{TABS_AND_SPACES}("integer"){TABS_AND_SPACES}")" { if (PARSER_MODE()) { zend_error(E_DEPRECATED, "Non-canonical cast (integer) is deprecated, use the (int) cast instead"); + if (PARSER_MODE() && EG(exception)) { + RETURN_TOKEN(T_ERROR); + } } RETURN_TOKEN(T_INT_CAST); } @@ -1647,6 +1655,9 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ "("{TABS_AND_SPACES}("double"){TABS_AND_SPACES}")" { if (PARSER_MODE()) { zend_error(E_DEPRECATED, "Non-canonical cast (double) is deprecated, use the (float) cast instead"); + if (PARSER_MODE() && EG(exception)) { + RETURN_TOKEN(T_ERROR); + } } RETURN_TOKEN(T_DOUBLE_CAST); } @@ -1666,6 +1677,9 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ "("{TABS_AND_SPACES}("binary"){TABS_AND_SPACES}")" { if (PARSER_MODE()) { zend_error(E_DEPRECATED, "Non-canonical cast (binary) is deprecated, use the (string) cast instead"); + if (PARSER_MODE() && EG(exception)) { + RETURN_TOKEN(T_ERROR); + } } RETURN_TOKEN(T_STRING_CAST); } @@ -1685,6 +1699,9 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ "("{TABS_AND_SPACES}("boolean"){TABS_AND_SPACES}")" { if (PARSER_MODE()) { zend_error(E_DEPRECATED, "Non-canonical cast (boolean) is deprecated, use the (bool) cast instead"); + if (PARSER_MODE() && EG(exception)) { + RETURN_TOKEN(T_ERROR); + } } RETURN_TOKEN(T_BOOL_CAST); } @@ -2741,6 +2758,7 @@ skip_escape_conversion: SCNG(heredoc_scan_ahead) = 1; SCNG(heredoc_indentation) = 0; SCNG(heredoc_indentation_uses_spaces) = 0; + SCNG(on_event_context) = NULL; LANG_SCNG(on_event) = NULL; CG(doc_comment) = NULL; diff --git a/ext/tokenizer/tests/gh19507_eval.phpt b/ext/tokenizer/tests/gh19507_eval.phpt new file mode 100644 index 0000000000000..e731cf818afbd --- /dev/null +++ b/ext/tokenizer/tests/gh19507_eval.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-19507: Corrupted result after recursive tokenization during token_get_all() (error handler with eval) +--EXTENSIONS-- +tokenizer +--FILE-- +getTokenName(), "\n"; +} +?> +--EXPECT-- +error handler called: Non-canonical cast (double) is deprecated, use the (float) cast instead +T_OPEN_TAG +T_DOUBLE_CAST +T_WHITESPACE +T_VARIABLE +; diff --git a/ext/tokenizer/tests/gh19507_throw.phpt b/ext/tokenizer/tests/gh19507_throw.phpt new file mode 100644 index 0000000000000..4449fe430538d --- /dev/null +++ b/ext/tokenizer/tests/gh19507_throw.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-19507: Corrupted result after recursive tokenization during token_get_all() (error handler with throw) +--EXTENSIONS-- +tokenizer +--FILE-- +getTokenName(), "\n"; +} +?> +--EXPECTF-- +Fatal error: Uncaught RuntimeException: error handler called: Non-canonical cast (double) is deprecated, use the (float) cast instead in %s:%d +Stack trace: +#0 [internal function]: {closure:%s:%d}(%d, 'Non-canonical c...', '', 1) +#1 %s(%d): PhpToken::tokenize('