Skip to content

Commit 035a5fd

Browse files
authored
Add LIBXML_RECOVER (#13504)
Setting the recovery option by using a hardcoded value (1) worked already for SimpleXML. For DOM, a small change is necessary because otherwise the recover field overwrites the recovery option. From a quick search on GitHub [1] it looks like this won't clash with existing PHP code as no one seems to define (or use) a constant with such a name. [1] https://github.com/search?q=LIBXML_RECOVER+language%3APHP&type=code&l=PHP
1 parent 79133df commit 035a5fd

9 files changed

+64
-5
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ PHP NEWS
7070
. Added LDAP_OPT_X_TLS_PROTOCOL_MAX/LDAP_OPT_X_TLS_PROTOCOL_TLS1_3
7171
constants. (StephenWall)
7272

73+
- LibXML:
74+
. Added LIBXML_RECOVER constant. (nielsdos)
75+
7376
- MBString:
7477
. Added mb_trim, mb_ltrim and mb_rtrim. (Yuya Hamada)
7578

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,9 @@ PHP 8.4 UPGRADE NOTES
484484
. LDAP_OPT_X_TLS_PROTOCOL_MAX.
485485
. LDAP_OPT_X_TLS_PROTOCOL_TLS1_3.
486486

487+
- LibXML:
488+
. LIBXML_RECOVER.
489+
487490
- OpenSSL:
488491
. X509_PURPOSE_OCSP_HELPER.
489492
. X509_PURPOSE_TIMESTAMP_SIGN.

ext/dom/document.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1261,7 +1261,7 @@ xmlDocPtr dom_document_parser(zval *id, dom_load_mode mode, const char *source,
12611261
resolve_externals = doc_props->resolveexternals;
12621262
keep_blanks = doc_props->preservewhitespace;
12631263
substitute_ent = doc_props->substituteentities;
1264-
recover = doc_props->recover;
1264+
recover = doc_props->recover || (options & XML_PARSE_RECOVER) == XML_PARSE_RECOVER;
12651265

12661266
xmlInitParser();
12671267

ext/dom/tests/modern/xml/XMLDocument_fromString_03.phpt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ dom
66
<?php
77

88
$flags = [
9-
LIBXML_NOENT, LIBXML_DTDLOAD, LIBXML_DTDATTR, LIBXML_DTDVALID, LIBXML_NOERROR, LIBXML_NOWARNING, LIBXML_NOBLANKS, LIBXML_XINCLUDE, LIBXML_NSCLEAN, LIBXML_NOCDATA, LIBXML_NONET, LIBXML_PEDANTIC, LIBXML_COMPACT, LIBXML_PARSEHUGE, LIBXML_BIGLINES
9+
LIBXML_RECOVER, LIBXML_NOENT, LIBXML_DTDLOAD, LIBXML_DTDATTR, LIBXML_DTDVALID, LIBXML_NOERROR, LIBXML_NOWARNING, LIBXML_NOBLANKS, LIBXML_XINCLUDE, LIBXML_NSCLEAN, LIBXML_NOCDATA, LIBXML_NONET, LIBXML_PEDANTIC, LIBXML_COMPACT, LIBXML_PARSEHUGE, LIBXML_BIGLINES
1010
];
1111

1212
try {
@@ -21,7 +21,8 @@ foreach ($flags as $flag) {
2121

2222
?>
2323
--EXPECT--
24-
DOM\XMLDocument::createFromString(): Argument #2 ($options) contains invalid flags (allowed flags: LIBXML_NOENT, LIBXML_DTDLOAD, LIBXML_DTDATTR, LIBXML_DTDVALID, LIBXML_NOERROR, LIBXML_NOWARNING, LIBXML_NOBLANKS, LIBXML_XINCLUDE, LIBXML_NSCLEAN, LIBXML_NOCDATA, LIBXML_NONET, LIBXML_PEDANTIC, LIBXML_COMPACT, LIBXML_PARSEHUGE, LIBXML_BIGLINES)bool(true)
24+
DOM\XMLDocument::createFromString(): Argument #2 ($options) contains invalid flags (allowed flags: LIBXML_RECOVER, LIBXML_NOENT, LIBXML_DTDLOAD, LIBXML_DTDATTR, LIBXML_DTDVALID, LIBXML_NOERROR, LIBXML_NOWARNING, LIBXML_NOBLANKS, LIBXML_XINCLUDE, LIBXML_NSCLEAN, LIBXML_NOCDATA, LIBXML_NONET, LIBXML_PEDANTIC, LIBXML_COMPACT, LIBXML_PARSEHUGE, LIBXML_BIGLINES)bool(true)
25+
bool(true)
2526
bool(true)
2627
bool(true)
2728
bool(true)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
XML parsing with LIBXML_RECOVER
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$dom = new DOMDocument;
9+
$dom->loadXML('<root><child/>', options: LIBXML_RECOVER);
10+
echo $dom->saveXML();
11+
12+
$dom = DOM\XMLDocument::createFromString('<root><child/>', options: LIBXML_RECOVER);
13+
echo $dom->saveXML(), "\n";
14+
15+
?>
16+
--EXPECTF--
17+
Warning: DOMDocument::loadXML(): %s
18+
<?xml version="1.0"?>
19+
<root><child/></root>
20+
21+
Warning: DOM\XMLDocument::createFromString(): %s
22+
<?xml version="1.0" encoding="UTF-8"?>
23+
<root><child/></root>

ext/dom/xml_document.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525

2626
static bool check_options_validity(uint32_t arg_num, zend_long options)
2727
{
28-
const zend_long VALID_OPTIONS = XML_PARSE_NOENT
28+
const zend_long VALID_OPTIONS = XML_PARSE_RECOVER
29+
| XML_PARSE_NOENT
2930
| XML_PARSE_DTDLOAD
3031
| XML_PARSE_DTDATTR
3132
| XML_PARSE_DTDVALID
@@ -42,6 +43,7 @@ static bool check_options_validity(uint32_t arg_num, zend_long options)
4243
| XML_PARSE_BIG_LINES;
4344
if ((options & ~VALID_OPTIONS) != 0) {
4445
zend_argument_value_error(2, "contains invalid flags (allowed flags: "
46+
"LIBXML_RECOVER, "
4547
"LIBXML_NOENT, "
4648
"LIBXML_DTDLOAD, "
4749
"LIBXML_DTDATTR, "

ext/libxml/libxml.stub.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
*/
1919
const LIBXML_LOADED_VERSION = UNKNOWN;
2020

21+
/**
22+
* @var int
23+
* @cvalue XML_PARSE_RECOVER
24+
*/
25+
const LIBXML_RECOVER = UNKNOWN;
2126
/**
2227
* @var int
2328
* @cvalue XML_PARSE_NOENT

ext/libxml/libxml_arginfo.h

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
XML parsing with LIBXML_RECOVER
3+
--EXTENSIONS--
4+
simplexml
5+
--FILE--
6+
<?php
7+
8+
var_dump(simplexml_load_string('<root><child/>', options: LIBXML_RECOVER));
9+
10+
?>
11+
--EXPECTF--
12+
Warning: simplexml_load_string(): %s
13+
14+
Warning: simplexml_load_string(): <root><child/> in %s on line %d
15+
16+
Warning: simplexml_load_string(): ^ in %s on line %d
17+
object(SimpleXMLElement)#1 (1) {
18+
["child"]=>
19+
object(SimpleXMLElement)#2 (0) {
20+
}
21+
}

0 commit comments

Comments
 (0)