diff --git a/NEWS b/NEWS index 4bd6e99b437..5b66fb559e3 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.4.0alpha2 -- PDO +- LibXML: + . Added LIBXML_NO_XXE constant. (nielsdos) + +- PDO: . Fixed bug GH-14792 (Compilation failure on pdo_* extensions). (Peter Kokot) diff --git a/UPGRADING b/UPGRADING index d72ce15cf0a..abc564135f8 100644 --- a/UPGRADING +++ b/UPGRADING @@ -763,6 +763,10 @@ PHP 8.4 UPGRADE NOTES - LibXML: . LIBXML_RECOVER. + . LIBXML_NO_XXE. + This is used together with LIBXML_NOENT for when you want to perform entity + substitution, but want to disallow external entity loading. + This constant is available as of libxml2 2.13. - OpenSSL: . X509_PURPOSE_OCSP_HELPER. diff --git a/ext/dom/tests/modern/xml/XMLDocument_fromString_03.phpt b/ext/dom/tests/modern/xml/XMLDocument_fromString_03.phpt index 4f29c01c264..13359f4b285 100644 --- a/ext/dom/tests/modern/xml/XMLDocument_fromString_03.phpt +++ b/ext/dom/tests/modern/xml/XMLDocument_fromString_03.phpt @@ -12,7 +12,7 @@ $flags = [ try { Dom\XMLDocument::createFromString('', -1); } catch (ValueError $e) { - echo $e->getMessage(); + echo $e->getMessage(), "\n"; } foreach ($flags as $flag) { @@ -20,8 +20,9 @@ foreach ($flags as $flag) { } ?> ---EXPECT-- -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) +--EXPECTF-- +Dom\XMLDocument::createFromString(): Argument #2 ($options) contains invalid flags (allowed flags: %s) +bool(true) bool(true) bool(true) bool(true) diff --git a/ext/dom/tests/xml_parsing_LIBXML_NO_XXE.phpt b/ext/dom/tests/xml_parsing_LIBXML_NO_XXE.phpt new file mode 100644 index 00000000000..9033ce50f9e --- /dev/null +++ b/ext/dom/tests/xml_parsing_LIBXML_NO_XXE.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test flag LIBXML_NO_XXE +--EXTENSIONS-- +dom +--SKIPIF-- + +--FILE-- + +bar'> + +]> +&foo;&xxe; +XML; + +$doc = Dom\XMLDocument::createFromString($xml, LIBXML_NOENT | LIBXML_NO_XXE); +echo $doc->saveXML(); +?> +--EXPECT-- + +bar"> + +]> +bar diff --git a/ext/dom/xml_document.c b/ext/dom/xml_document.c index 59b8b1178ae..e1511b65ef7 100644 --- a/ext/dom/xml_document.c +++ b/ext/dom/xml_document.c @@ -29,6 +29,9 @@ static bool check_options_validity(uint32_t arg_num, zend_long options) { const zend_long VALID_OPTIONS = XML_PARSE_RECOVER | XML_PARSE_NOENT +#if LIBXML_VERSION >= 21300 + | XML_PARSE_NO_XXE +#endif | XML_PARSE_DTDLOAD | XML_PARSE_DTDATTR | XML_PARSE_DTDVALID @@ -47,6 +50,9 @@ static bool check_options_validity(uint32_t arg_num, zend_long options) zend_argument_value_error(arg_num, "contains invalid flags (allowed flags: " "LIBXML_RECOVER, " "LIBXML_NOENT, " +#if LIBXML_VERSION >= 21300 + "LIBXML_NO_XXE, " +#endif "LIBXML_DTDLOAD, " "LIBXML_DTDATTR, " "LIBXML_DTDVALID, " diff --git a/ext/libxml/libxml.stub.php b/ext/libxml/libxml.stub.php index ac9220c4f1d..231d7f5368c 100644 --- a/ext/libxml/libxml.stub.php +++ b/ext/libxml/libxml.stub.php @@ -28,6 +28,13 @@ const LIBXML_RECOVER = UNKNOWN; * @cvalue XML_PARSE_NOENT */ const LIBXML_NOENT = UNKNOWN; +#if LIBXML_VERSION >= 21300 +/** + * @var int + * @cvalue XML_PARSE_NO_XXE + */ +const LIBXML_NO_XXE = UNKNOWN; +#endif /** * @var int * @cvalue XML_PARSE_DTDLOAD diff --git a/ext/libxml/libxml_arginfo.h b/ext/libxml/libxml_arginfo.h index a4c072a9b02..fe50c20c220 100644 --- a/ext/libxml/libxml_arginfo.h +++ b/ext/libxml/libxml_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 08e4e3f10ba89430292831f50c4760a362593282 */ + * Stub hash: 9baeff96436234ec51bd329477c6143caca7dd20 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_libxml_set_streams_context, 0, 1, IS_VOID, 0) ZEND_ARG_INFO(0, context) @@ -61,6 +61,9 @@ static void register_libxml_symbols(int module_number) REGISTER_STRING_CONSTANT("LIBXML_LOADED_VERSION", PHP_LIBXML_LOADED_VERSION, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("LIBXML_RECOVER", XML_PARSE_RECOVER, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("LIBXML_NOENT", XML_PARSE_NOENT, CONST_PERSISTENT); +#if LIBXML_VERSION >= 21300 + REGISTER_LONG_CONSTANT("LIBXML_NO_XXE", XML_PARSE_NO_XXE, CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("LIBXML_DTDLOAD", XML_PARSE_DTDLOAD, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("LIBXML_DTDATTR", XML_PARSE_DTDATTR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("LIBXML_DTDVALID", XML_PARSE_DTDVALID, CONST_PERSISTENT); diff --git a/ext/simplexml/tests/xml_parsing_LIBXML_NO_XXE.phpt b/ext/simplexml/tests/xml_parsing_LIBXML_NO_XXE.phpt new file mode 100644 index 00000000000..c80c70a1d0b --- /dev/null +++ b/ext/simplexml/tests/xml_parsing_LIBXML_NO_XXE.phpt @@ -0,0 +1,28 @@ +--TEST-- +XML parsing with LIBXML_NO_XXE +--EXTENSIONS-- +simplexml +--SKIPIF-- + +--FILE-- + +bar'> + +]> +&foo;&xxe; +XML; + +var_dump(simplexml_load_string($xml, options: LIBXML_NOENT | LIBXML_NO_XXE)); + +?> +--EXPECT-- +object(SimpleXMLElement)#1 (1) { + ["foo"]=> + string(3) "bar" +}