From 2362af2e647d62a4d0d0b0bb150fe900a816da34 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 13 Sep 2024 18:22:38 +0200 Subject: [PATCH] Fix GH-15868: Assertion failure in xml_parse_into_struct after exception Upon unwinding from an exception, the parser state is not stable, we should not continue updating the values if an exception was thrown. --- ext/xml/tests/gh15868.phpt | 46 ++++++++++++++++++++++++++++++++++++++ ext/xml/xml.c | 6 ++--- 2 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 ext/xml/tests/gh15868.phpt diff --git a/ext/xml/tests/gh15868.phpt b/ext/xml/tests/gh15868.phpt new file mode 100644 index 000000000000..17ed80558d78 --- /dev/null +++ b/ext/xml/tests/gh15868.phpt @@ -0,0 +1,46 @@ +--TEST-- +GH-15868 (Assertion failure in xml_parse_into_struct after exception) +--EXTENSIONS-- +xml +--FILE-- +", $values, $tags); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$parser = xml_parser_create(); +xml_set_element_handler($parser, + function ($parser, $name, $attrs) { + }, function ($parser, $name) { + throw new Error('stop 2'); + } +); +try { + xml_parse_into_struct($parser, "", $values, $tags); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$parser = xml_parser_create(); +xml_set_character_data_handler($parser, function() { + throw new Error('stop 3'); +}); +try { + xml_parse_into_struct($parser, "", $values, $tags); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +stop 1 +stop 2 +stop 3 diff --git a/ext/xml/xml.c b/ext/xml/xml.c index 59d50faed111..eef78474281b 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -628,7 +628,7 @@ void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Ch zval_ptr_dtor(&retval); } - if (!Z_ISUNDEF(parser->data)) { + if (!Z_ISUNDEF(parser->data) && !EG(exception)) { if (parser->level <= XML_MAXLEVEL) { zval tag, atr; int atcnt = 0; @@ -699,7 +699,7 @@ void _xml_endElementHandler(void *userData, const XML_Char *name) zval_ptr_dtor(&retval); } - if (!Z_ISUNDEF(parser->data)) { + if (!Z_ISUNDEF(parser->data) && !EG(exception)) { zval tag; if (parser->lastwasopen) { @@ -747,7 +747,7 @@ void _xml_characterDataHandler(void *userData, const XML_Char *s, int len) zval_ptr_dtor(&retval); } - if (Z_ISUNDEF(parser->data)) { + if (Z_ISUNDEF(parser->data) || EG(exception)) { return; }