Skip to content

Commit 80a377e

Browse files
committed
Fix #81351: xml_parse may fail, but has no error code
The fix for bug #73151[1] cured the symptoms, but not the root cause, namely xmlParse() must not be called recursively. Since that bugfix also messed up the error handling, we basically revert it (but also simplify the return), and then prevent calling the parser recursively. [1] <php@f2a8a8c> Co-authored-by: Nikita Popov <[email protected]> Closes phpGH-7363.
1 parent 78cbe56 commit 80a377e

File tree

5 files changed

+44
-9
lines changed

5 files changed

+44
-9
lines changed

Diff for: NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ PHP NEWS
77
. Fixed bug #81346 (Non-seekable streams don't update position after write).
88
(cmb)
99

10+
- XML:
11+
. Fixed bug #81351 (xml_parse may fail, but has no error code). (cmb, Nikita)
12+
1013
26 Aug 2021, PHP 7.4.23
1114

1215
- Core:

Diff for: ext/xml/compat.c

+1-9
Original file line numberDiff line numberDiff line change
@@ -565,16 +565,8 @@ XML_Parse(XML_Parser parser, const XML_Char *data, int data_len, int is_final)
565565
{
566566
int error;
567567

568-
if (parser->parser->lastError.level >= XML_ERR_WARNING) {
569-
return 0;
570-
}
571-
572568
error = xmlParseChunk(parser->parser, (char *) data, data_len, is_final);
573-
if (error) {
574-
return 0;
575-
} else {
576-
return 1;
577-
}
569+
return !error && parser->parser->lastError.level <= XML_ERR_WARNING;
578570
}
579571

580572
PHP_XML_API int

Diff for: ext/xml/tests/bug73135.phpt

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ HERE;
2121
xml_parse($parser, $xml);
2222
?>
2323
--EXPECTF--
24+
Warning: xml_parse(): Parser must not be called recursively in %s%ebug73135.php on line %d
25+
26+
Warning: xml_parse(): Parser must not be called recursively in %s%ebug73135.php on line %d
27+
2428
Warning: xml_parse(): Unable to call handler ahihi() in %s%ebug73135.php on line %d
2529

2630
Warning: xml_parse(): Unable to call handler ahihi() in %s%ebug73135.php on line %d

Diff for: ext/xml/tests/bug81351.phpt

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Bug #81351 (xml_parse may fail, but has no error code)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('xml')) die("skip xml extension not available");
6+
?>
7+
--FILE--
8+
<?php
9+
$xml = <<<XML
10+
<?xml version="1.0" encoding="utf-8"?>
11+
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
12+
<soap:Body>
13+
<X xmlns="example.org">
14+
XML;
15+
16+
$parser = xml_parser_create_ns('UTF-8');
17+
$success = xml_parse($parser, $xml, false);
18+
$code = xml_get_error_code($parser);
19+
$error = xml_error_string($code);
20+
echo "xml_parse returned $success, xml_get_error_code = $code, xml_error_string = $error\r\n";
21+
$success = xml_parse($parser, 'Y>', true);
22+
$code = xml_get_error_code($parser);
23+
$error = xml_error_string($code);
24+
echo "xml_parse returned $success, xml_get_error_code = $code, xml_error_string = $error\r\n";
25+
?>
26+
--EXPECT--
27+
xml_parse returned 1, xml_get_error_code = 0, xml_error_string = No error
28+
xml_parse returned 0, xml_get_error_code = 5, xml_error_string = Invalid document end

Diff for: ext/xml/xml.c

+8
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,10 @@ PHP_FUNCTION(xml_parse)
14161416
RETURN_FALSE;
14171417
}
14181418

1419+
if (parser->isparsing) {
1420+
php_error_docref(NULL, E_WARNING, "Parser must not be called recursively");
1421+
RETURN_FALSE;
1422+
}
14191423
parser->isparsing = 1;
14201424
ret = XML_Parse(parser->parser, (XML_Char*)data, data_len, isFinal);
14211425
parser->isparsing = 0;
@@ -1467,6 +1471,10 @@ PHP_FUNCTION(xml_parse_into_struct)
14671471
XML_SetElementHandler(parser->parser, _xml_startElementHandler, _xml_endElementHandler);
14681472
XML_SetCharacterDataHandler(parser->parser, _xml_characterDataHandler);
14691473

1474+
if (parser->isparsing) {
1475+
php_error_docref(NULL, E_WARNING, "Parser must not be called recursively");
1476+
RETURN_FALSE;
1477+
}
14701478
parser->isparsing = 1;
14711479
ret = XML_Parse(parser->parser, (XML_Char*)data, data_len, 1);
14721480
parser->isparsing = 0;

0 commit comments

Comments
 (0)