diff options
Diffstat (limited to 'ext/xml')
43 files changed, 1000 insertions, 884 deletions
diff --git a/ext/xml/compat.c b/ext/xml/compat.c index be988a822f..aaef302ef2 100644 --- a/ext/xml/compat.c +++ b/ext/xml/compat.c @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | diff --git a/ext/xml/expat_compat.h b/ext/xml/expat_compat.h index 350d42f0c6..e5673be779 100644 --- a/ext/xml/expat_compat.h +++ b/ext/xml/expat_compat.h @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | diff --git a/ext/xml/php_xml.h b/ext/xml/php_xml.h index f8bb415f32..56d983b451 100644 --- a/ext/xml/php_xml.h +++ b/ext/xml/php_xml.h @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | diff --git a/ext/xml/tests/bug25666.phpt b/ext/xml/tests/bug25666.phpt index e162d5a2bd..ca4b15f405 100644 --- a/ext/xml/tests/bug25666.phpt +++ b/ext/xml/tests/bug25666.phpt @@ -8,7 +8,7 @@ if (! @xml_parser_create_ns('ISO-8859-1')) { die("skip xml_parser_create_ns is n --FILE-- <?php function start_elem($parser,$name,$attribs) { - var_dump($name); + var_dump($name); } function end_elem() { @@ -17,7 +17,7 @@ function end_elem() $xml = <<<HERE <foo:a xmlns:foo="http://example.com/foo" xmlns:bar="http://example.com/bar" - xmlns:baz="http://example.com/baz"> + xmlns:baz="http://example.com/baz"> <bar:b /> <baz:c /> </foo> diff --git a/ext/xml/tests/bug26528.phpt b/ext/xml/tests/bug26528.phpt index 96da841004..152a18540d 100644 --- a/ext/xml/tests/bug26528.phpt +++ b/ext/xml/tests/bug26528.phpt @@ -6,11 +6,11 @@ require_once("skipif.inc"); ?> --FILE-- <?php - $sample = "<?xml version=\"1.0\"?><test attr=\"angle<bracket\"/>"; - $parser = xml_parser_create(); - $res = xml_parse_into_struct($parser,$sample,$vals,$index); - xml_parser_free($parser); - var_dump($vals); + $sample = "<?xml version=\"1.0\"?><test attr=\"angle<bracket\"/>"; + $parser = xml_parser_create(); + $res = xml_parse_into_struct($parser,$sample,$vals,$index); + xml_parser_free($parser); + var_dump($vals); ?> --EXPECT-- array(1) { diff --git a/ext/xml/tests/bug26614.phpt b/ext/xml/tests/bug26614.phpt index c95997a8a6..ed42bc1fbf 100644 --- a/ext/xml/tests/bug26614.phpt +++ b/ext/xml/tests/bug26614.phpt @@ -25,7 +25,7 @@ $xmls["CDATA"] ='<?xml version="1.0" encoding="iso-8859-1" ?> <data> <![CDATA[ multi -line +line CDATA block ]]> @@ -36,7 +36,7 @@ $xmls["Comment"] ='<?xml version="1.0" encoding="iso-8859-1" ?> <data> <!-- ATA[ multi -line +line CDATA block --> @@ -47,7 +47,7 @@ $xmls["Text"] ='<?xml version="1.0" encoding="iso-8859-1" ?> <data> -!-- ATA[ multi -line +line CDATA block --- @@ -55,16 +55,16 @@ block function startElement($parser, $name, $attrs) { printf("<$name> at line %d, col %d (byte %d)\n", - xml_get_current_line_number($parser), - xml_get_current_column_number($parser), - xml_get_current_byte_index($parser)); + xml_get_current_line_number($parser), + xml_get_current_column_number($parser), + xml_get_current_byte_index($parser)); } function endElement($parser, $name) { printf("</$name> at line %d, col %d (byte %d)\n", - xml_get_current_line_number($parser), - xml_get_current_column_number($parser), - xml_get_current_byte_index($parser)); + xml_get_current_line_number($parser), + xml_get_current_column_number($parser), + xml_get_current_byte_index($parser)); } function characterData($parser, $data) { @@ -73,12 +73,12 @@ function characterData($parser, $data) { foreach ($xmls as $desc => $xml) { echo "$desc\n"; - $xml_parser = xml_parser_create(); - xml_set_element_handler($xml_parser, "startElement", "endElement"); - xml_set_character_data_handler($xml_parser, "characterData"); - if (!xml_parse($xml_parser, $xml, true)) - echo "Error: ".xml_error_string(xml_get_error_code($xml_parser))."\n"; - xml_parser_free($xml_parser); + $xml_parser = xml_parser_create(); + xml_set_element_handler($xml_parser, "startElement", "endElement"); + xml_set_character_data_handler($xml_parser, "characterData"); + if (!xml_parse($xml_parser, $xml, true)) + echo "Error: ".xml_error_string(xml_get_error_code($xml_parser))."\n"; + xml_parser_free($xml_parser); } ?> --EXPECT-- diff --git a/ext/xml/tests/bug26614_libxml.phpt b/ext/xml/tests/bug26614_libxml.phpt index 3ddd35ed0e..b6c0b87581 100644 --- a/ext/xml/tests/bug26614_libxml.phpt +++ b/ext/xml/tests/bug26614_libxml.phpt @@ -12,7 +12,7 @@ this test works fine with Expat but fails with libxml which we now use as default further investigation has shown that not only line count -is skippet on CDATA sections but that libxml does also +is skipped on CDATA sections but that libxml does also show different column numbers and byte positions depending on context and in opposition to what one would expect to see and what good old Expat reported just fine ... @@ -25,7 +25,7 @@ $xmls["CDATA"] ='<?xml version="1.0" encoding="iso-8859-1" ?> <data> <![CDATA[ multi -line +line CDATA block ]]> @@ -36,7 +36,7 @@ $xmls["Comment"] ='<?xml version="1.0" encoding="iso-8859-1" ?> <data> <!-- ATA[ multi -line +line CDATA block --> @@ -47,7 +47,7 @@ $xmls["Text"] ='<?xml version="1.0" encoding="iso-8859-1" ?> <data> -!-- ATA[ multi -line +line CDATA block --- @@ -55,16 +55,16 @@ block function startElement($parser, $name, $attrs) { printf("<$name> at line %d, col %d (byte %d)\n", - xml_get_current_line_number($parser), - xml_get_current_column_number($parser), - xml_get_current_byte_index($parser)); + xml_get_current_line_number($parser), + xml_get_current_column_number($parser), + xml_get_current_byte_index($parser)); } function endElement($parser, $name) { printf("</$name> at line %d, col %d (byte %d)\n", - xml_get_current_line_number($parser), - xml_get_current_column_number($parser), - xml_get_current_byte_index($parser)); + xml_get_current_line_number($parser), + xml_get_current_column_number($parser), + xml_get_current_byte_index($parser)); } function characterData($parser, $data) { @@ -73,21 +73,21 @@ function characterData($parser, $data) { foreach ($xmls as $desc => $xml) { echo "$desc\n"; - $xml_parser = xml_parser_create(); - xml_set_element_handler($xml_parser, "startElement", "endElement"); - xml_set_character_data_handler($xml_parser, "characterData"); - if (!xml_parse($xml_parser, $xml, true)) - echo "Error: ".xml_error_string(xml_get_error_code($xml_parser))."\n"; - xml_parser_free($xml_parser); + $xml_parser = xml_parser_create(); + xml_set_element_handler($xml_parser, "startElement", "endElement"); + xml_set_character_data_handler($xml_parser, "characterData"); + if (!xml_parse($xml_parser, $xml, true)) + echo "Error: ".xml_error_string(xml_get_error_code($xml_parser))."\n"; + xml_parser_free($xml_parser); } ?> --EXPECTF-- CDATA <DATA> at line 2, col %d (byte 9) -</DATA> at line 9, col %d (byte 56) +</DATA> at line 9, col %d (byte 55) Comment <DATA> at line 2, col %d (byte 9) -</DATA> at line 9, col %d (byte 56) +</DATA> at line 9, col %d (byte 55) Text <DATA> at line 2, col %d (byte 9) -</DATA> at line 9, col %d (byte 56) +</DATA> at line 9, col %d (byte 55) diff --git a/ext/xml/tests/bug30266.phpt b/ext/xml/tests/bug30266.phpt index 2cf0a68cde..a7fe7592fe 100644 --- a/ext/xml/tests/bug30266.phpt +++ b/ext/xml/tests/bug30266.phpt @@ -33,7 +33,7 @@ class XML_Parser function startHandler($XmlParser, $tag, $attr) { $this->dummy = "b"; - throw new Exception("ex"); + throw new Exception("ex"); } function endHandler($XmlParser, $tag) @@ -45,7 +45,7 @@ $p1 = new Xml_Parser(); try { $p1->parse('<tag1><tag2></tag2></tag1>'); } catch (Exception $e) { - echo "OK\n"; + echo "OK\n"; } ?> --EXPECT-- diff --git a/ext/xml/tests/bug30875.phpt b/ext/xml/tests/bug30875.phpt index c5254e9668..c7983c45da 100644 --- a/ext/xml/tests/bug30875.phpt +++ b/ext/xml/tests/bug30875.phpt @@ -19,7 +19,6 @@ xml_parse_into_struct($parser, $xml, $vals); xml_parser_free($parser); var_dump($vals); ?> -===DONE=== --EXPECT-- array(1) { [0]=> @@ -39,4 +38,3 @@ array(1) { string(4) "aent" } } -===DONE=== diff --git a/ext/xml/tests/bug32001.phpt b/ext/xml/tests/bug32001.phpt index 2e2f4643d5..410a2f62ff 100644 --- a/ext/xml/tests/bug32001.phpt +++ b/ext/xml/tests/bug32001.phpt @@ -5,151 +5,151 @@ Bug #32001 (xml_parse*() goes into infinite loop when autodetection in effect), require_once("skipif.inc"); if (!extension_loaded('iconv')) die ("skip iconv extension not available"); if (ICONV_IMPL == 'glibc' && version_compare(ICONV_VERSION, '2.12', '<=')) - die("skip iconv of glibc <= 2.12 is buggy"); + die("skip iconv of glibc <= 2.12 is buggy"); ?> --FILE-- <?php class testcase { - private $encoding; - private $bom; - private $prologue; - private $tags; - private $chunk_size; + private $encoding; + private $bom; + private $prologue; + private $tags; + private $chunk_size; - function __construct($enc, $chunk_size = 0, $bom = 0, $omit_prologue = 0) { - $this->encoding = $enc; - $this->chunk_size = $chunk_size; - $this->bom = $bom; - $this->prologue = !$omit_prologue; - $this->tags = array(); - } + function __construct($enc, $chunk_size = 0, $bom = 0, $omit_prologue = 0) { + $this->encoding = $enc; + $this->chunk_size = $chunk_size; + $this->bom = $bom; + $this->prologue = !$omit_prologue; + $this->tags = array(); + } - function start_element($parser, $name, $attrs) { - $attrs = array_map('bin2hex', $attrs); - $this->tags[] = bin2hex($name).": ".implode(', ', $attrs); - } + function start_element($parser, $name, $attrs) { + $attrs = array_map('bin2hex', $attrs); + $this->tags[] = bin2hex($name).": ".implode(', ', $attrs); + } - function end_element($parser, $name) { - } + function end_element($parser, $name) { + } - function run() { - $data = ''; + function run() { + $data = ''; - if ($this->prologue) { - $canonical_name = preg_replace('/BE|LE/i', '', $this->encoding); - $data .= "<?xml version=\"1.0\" encoding=\"$canonical_name\" ?>\n"; - } + if ($this->prologue) { + $canonical_name = preg_replace('/BE|LE/i', '', $this->encoding); + $data .= "<?xml version=\"1.0\" encoding=\"$canonical_name\" ?>\n"; + } - $data .= <<<HERE + $data .= <<<HERE <テスト:テスト1 xmlns:テスト="http://www.example.com/テスト/" テスト="テスト"> <テスト:テスト2 テスト="テスト"> - <テスト:テスト3> - test! - </テスト:テスト3> + <テスト:テスト3> + test! + </テスト:テスト3> </テスト:テスト2> </テスト:テスト1> HERE; - $data = iconv("UTF-8", $this->encoding, $data); + $data = iconv("UTF-8", $this->encoding, $data); - if ($this->bom) { - switch (strtoupper($this->encoding)) { - case 'UTF-8': - case 'UTF8': - $data = "\xef\xbb\xbf".$data; - break; + if ($this->bom) { + switch (strtoupper($this->encoding)) { + case 'UTF-8': + case 'UTF8': + $data = "\xef\xbb\xbf".$data; + break; - case 'UTF-16': - case 'UTF16': - case 'UTF-16BE': - case 'UTF16BE': - case 'UCS-2': - case 'UCS2': - case 'UCS-2BE': - case 'UCS2BE': - $data = "\xfe\xff".$data; - break; + case 'UTF-16': + case 'UTF16': + case 'UTF-16BE': + case 'UTF16BE': + case 'UCS-2': + case 'UCS2': + case 'UCS-2BE': + case 'UCS2BE': + $data = "\xfe\xff".$data; + break; - case 'UTF-16LE': - case 'UTF16LE': - case 'UCS-2LE': - case 'UCS2LE': - $data = "\xff\xfe".$data; - break; + case 'UTF-16LE': + case 'UTF16LE': + case 'UCS-2LE': + case 'UCS2LE': + $data = "\xff\xfe".$data; + break; - case 'UTF-32': - case 'UTF32': - case 'UTF-32BE': - case 'UTF32BE': - case 'UCS-4': - case 'UCS4': - case 'UCS-4BE': - case 'UCS4BE': - $data = "\x00\x00\xfe\xff".$data; - break; + case 'UTF-32': + case 'UTF32': + case 'UTF-32BE': + case 'UTF32BE': + case 'UCS-4': + case 'UCS4': + case 'UCS-4BE': + case 'UCS4BE': + $data = "\x00\x00\xfe\xff".$data; + break; - case 'UTF-32LE': - case 'UTF32LE': - case 'UCS-4LE': - case 'UCS4LE': - $data = "\xff\xfe\x00\x00".$data; - break; - } - } + case 'UTF-32LE': + case 'UTF32LE': + case 'UCS-4LE': + case 'UCS4LE': + $data = "\xff\xfe\x00\x00".$data; + break; + } + } - $parser = xml_parser_create(NULL); - xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); - xml_set_element_handler($parser, "start_element", "end_element"); - xml_set_object($parser, $this); + $parser = xml_parser_create(NULL); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); + xml_set_element_handler($parser, "start_element", "end_element"); + xml_set_object($parser, $this); - if ($this->chunk_size == 0) { - $success = @xml_parse($parser, $data, true); - } else { - for ($offset = 0; $offset < strlen($data); - $offset += $this->chunk_size) { - $success = @xml_parse($parser, substr($data, $offset, $this->chunk_size), false); - if (!$success) { - break; - } - } - if ($success) { - $success = @xml_parse($parser, "", true); - } - } + if ($this->chunk_size == 0) { + $success = @xml_parse($parser, $data, true); + } else { + for ($offset = 0; $offset < strlen($data); + $offset += $this->chunk_size) { + $success = @xml_parse($parser, substr($data, $offset, $this->chunk_size), false); + if (!$success) { + break; + } + } + if ($success) { + $success = @xml_parse($parser, "", true); + } + } - echo "Encoding: $this->encoding\n"; - echo "XML Prologue: ".($this->prologue ? 'present': 'not present'), "\n"; - echo "Chunk size: ".($this->chunk_size ? "$this->chunk_size byte(s)\n": "all data at once\n"); - echo "BOM: ".($this->bom ? 'prepended': 'not prepended'), "\n"; + echo "Encoding: $this->encoding\n"; + echo "XML Prologue: ".($this->prologue ? 'present': 'not present'), "\n"; + echo "Chunk size: ".($this->chunk_size ? "$this->chunk_size byte(s)\n": "all data at once\n"); + echo "BOM: ".($this->bom ? 'prepended': 'not prepended'), "\n"; - if ($success) { - var_dump($this->tags); - } else { - echo "[Error] ", xml_error_string(xml_get_error_code($parser)), "\n"; - } - } + if ($success) { + var_dump($this->tags); + } else { + echo "[Error] ", xml_error_string(xml_get_error_code($parser)), "\n"; + } + } } $suite = array( - new testcase("UTF-8", 0, 0, 0), - new testcase("UTF-8", 0, 0, 1), - new testcase("UTF-8", 0, 1, 0), - new testcase("UTF-8", 0, 1, 1), - new testcase("UTF-16BE", 0, 0, 0), - new testcase("UTF-16BE", 0, 1, 0), - new testcase("UTF-16BE", 0, 1, 1), - new testcase("UTF-16LE", 0, 0, 0), - new testcase("UTF-16LE", 0, 1, 0), - new testcase("UTF-16LE", 0, 1, 1), - new testcase("UTF-8", 1, 0, 0), - new testcase("UTF-8", 1, 0, 1), - new testcase("UTF-8", 1, 1, 0), - new testcase("UTF-8", 1, 1, 1), - new testcase("UTF-16BE", 1, 0, 0), - new testcase("UTF-16BE", 1, 1, 0), - new testcase("UTF-16BE", 1, 1, 1), - new testcase("UTF-16LE", 1, 0, 0), - new testcase("UTF-16LE", 1, 1, 0), - new testcase("UTF-16LE", 1, 1, 1), + new testcase("UTF-8", 0, 0, 0), + new testcase("UTF-8", 0, 0, 1), + new testcase("UTF-8", 0, 1, 0), + new testcase("UTF-8", 0, 1, 1), + new testcase("UTF-16BE", 0, 0, 0), + new testcase("UTF-16BE", 0, 1, 0), + new testcase("UTF-16BE", 0, 1, 1), + new testcase("UTF-16LE", 0, 0, 0), + new testcase("UTF-16LE", 0, 1, 0), + new testcase("UTF-16LE", 0, 1, 1), + new testcase("UTF-8", 1, 0, 0), + new testcase("UTF-8", 1, 0, 1), + new testcase("UTF-8", 1, 1, 0), + new testcase("UTF-8", 1, 1, 1), + new testcase("UTF-16BE", 1, 0, 0), + new testcase("UTF-16BE", 1, 1, 0), + new testcase("UTF-16BE", 1, 1, 1), + new testcase("UTF-16LE", 1, 0, 0), + new testcase("UTF-16LE", 1, 1, 0), + new testcase("UTF-16LE", 1, 1, 1), ); if (XML_SAX_IMPL == 'libxml') { @@ -159,7 +159,7 @@ if (XML_SAX_IMPL == 'libxml') { } foreach ($suite as $testcase) { - $testcase->run(); + $testcase->run(); } ?> diff --git a/ext/xml/tests/bug32001b.phpt b/ext/xml/tests/bug32001b.phpt index 3a3c11a3ba..b88136b973 100644 --- a/ext/xml/tests/bug32001b.phpt +++ b/ext/xml/tests/bug32001b.phpt @@ -5,93 +5,97 @@ Bug #32001 (xml_parse*() goes into infinite loop when autodetection in effect), require_once("skipif.inc"); if (!extension_loaded('iconv')) die ("skip iconv extension not available"); foreach(array('EUC-JP', 'Shift_JISP', 'GB2312') as $encoding) { - if (@xml_parser_create($encoding) === false) die("skip libxml2 does not support $encoding encoding"); + try { + xml_parser_create($encoding); + } catch (ValueError) { + die("skip libxml2 does not support $encoding encoding"); + } } ?> --FILE-- <?php class testcase { - private $encoding; - private $bom; - private $prologue; - private $tags; - private $chunk_size; + private $encoding; + private $bom; + private $prologue; + private $tags; + private $chunk_size; - function testcase($enc, $chunk_size = 0, $bom = 0, $omit_prologue = 0) { - $this->encoding = $enc; - $this->chunk_size = $chunk_size; - $this->bom = $bom; - $this->prologue = !$omit_prologue; - $this->tags = array(); - } + function testcase($enc, $chunk_size = 0, $bom = 0, $omit_prologue = 0) { + $this->encoding = $enc; + $this->chunk_size = $chunk_size; + $this->bom = $bom; + $this->prologue = !$omit_prologue; + $this->tags = array(); + } - function start_element($parser, $name, $attrs) { - $attrs = array_map('bin2hex', $attrs); - $this->tags[] = bin2hex($name).": ".implode(', ', $attrs); - } + function start_element($parser, $name, $attrs) { + $attrs = array_map('bin2hex', $attrs); + $this->tags[] = bin2hex($name).": ".implode(', ', $attrs); + } - function end_element($parser, $name) { - } + function end_element($parser, $name) { + } - function run() { - $data = ''; + function run() { + $data = ''; - if ($this->prologue) { - $canonical_name = preg_replace('/BE|LE/i', '', $this->encoding); - $data .= "<?xml version=\"1.0\" encoding=\"$canonical_name\" ?>\n"; - } + if ($this->prologue) { + $canonical_name = preg_replace('/BE|LE/i', '', $this->encoding); + $data .= "<?xml version=\"1.0\" encoding=\"$canonical_name\" ?>\n"; + } - $data .= <<<HERE + $data .= <<<HERE <テスト:テスト1 xmlns:テスト="http://www.example.com/テスト/" テスト="テスト"> <テスト:テスト2 テスト="テスト"> - <テスト:テスト3> - test! - </テスト:テスト3> + <テスト:テスト3> + test! + </テスト:テスト3> </テスト:テスト2> </テスト:テスト1> HERE; - $data = iconv("UTF-8", $this->encoding, $data); + $data = iconv("UTF-8", $this->encoding, $data); - $parser = xml_parser_create(NULL); - xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); - xml_set_element_handler($parser, "start_element", "end_element"); - xml_set_object($parser, $this); + $parser = xml_parser_create(NULL); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); + xml_set_element_handler($parser, "start_element", "end_element"); + xml_set_object($parser, $this); - if ($this->chunk_size == 0) { - $success = @xml_parse($parser, $data, true); - } else { - for ($offset = 0; $offset < strlen($data); - $offset += $this->chunk_size) { - $success = @xml_parse($parser, substr($data, $offset, $this->chunk_size), false); - if (!$success) { - break; - } - } - if ($success) { - $success = @xml_parse($parser, "", true); - } - } + if ($this->chunk_size == 0) { + $success = @xml_parse($parser, $data, true); + } else { + for ($offset = 0; $offset < strlen($data); + $offset += $this->chunk_size) { + $success = @xml_parse($parser, substr($data, $offset, $this->chunk_size), false); + if (!$success) { + break; + } + } + if ($success) { + $success = @xml_parse($parser, "", true); + } + } - echo "Encoding: $this->encoding\n"; - echo "XML Prologue: ".($this->prologue ? 'present': 'not present'), "\n"; - echo "Chunk size: ".($this->chunk_size ? "$this->chunk_size byte(s)\n": "all data at once\n"); - echo "BOM: ".($this->bom ? 'prepended': 'not prepended'), "\n"; + echo "Encoding: $this->encoding\n"; + echo "XML Prologue: ".($this->prologue ? 'present': 'not present'), "\n"; + echo "Chunk size: ".($this->chunk_size ? "$this->chunk_size byte(s)\n": "all data at once\n"); + echo "BOM: ".($this->bom ? 'prepended': 'not prepended'), "\n"; - if ($success) { - var_dump($this->tags); - } else { - echo "[Error] ", xml_error_string(xml_get_error_code($parser)), "\n"; - } - } + if ($success) { + var_dump($this->tags); + } else { + echo "[Error] ", xml_error_string(xml_get_error_code($parser)), "\n"; + } + } } $suite = array( - new testcase("EUC-JP" , 0), - new testcase("EUC-JP" , 1), - new testcase("Shift_JIS", 0), - new testcase("Shift_JIS", 1), - new testcase("GB2312", 0), - new testcase("GB2312", 1), + new testcase("EUC-JP" , 0), + new testcase("EUC-JP" , 1), + new testcase("Shift_JIS", 0), + new testcase("Shift_JIS", 1), + new testcase("GB2312", 0), + new testcase("GB2312", 1), ); if (XML_SAX_IMPL == 'libxml') { @@ -101,7 +105,7 @@ if (XML_SAX_IMPL == 'libxml') { } foreach ($suite as $testcase) { - $testcase->run(); + $testcase->run(); } ?> diff --git a/ext/xml/tests/bug35447.phpt b/ext/xml/tests/bug35447.phpt index 8cbb5e5193..0f5f5581d0 100644 --- a/ext/xml/tests/bug35447.phpt +++ b/ext/xml/tests/bug35447.phpt @@ -3,7 +3,7 @@ Bug #35447 (xml_parse_into_struct() chokes on the UTF-8 BOM) --SKIPIF-- <?php require_once("skipif.inc"); -if (! @xml_parser_create_ns('ISO-8859-1')) { die("skip xml_parser_create_ns is not supported on this plattform");} +if (! @xml_parser_create_ns('ISO-8859-1')) { die("skip xml_parser_create_ns is not supported on this platform");} ?> --FILE-- <?php diff --git a/ext/xml/tests/bug71592.phpt b/ext/xml/tests/bug71592.phpt index e76e7b4ef6..260ea989d9 100644 --- a/ext/xml/tests/bug71592.phpt +++ b/ext/xml/tests/bug71592.phpt @@ -26,7 +26,5 @@ xml_set_external_entity_ref_handler($parser, function () { xml_parse($parser, $xml); var_dump(xml_get_error_code($parser) === XML_ERROR_EXTERNAL_ENTITY_HANDLING); ?> -===DONE=== --EXPECT-- bool(true) -===DONE=== diff --git a/ext/xml/tests/bug72085.phpt b/ext/xml/tests/bug72085.phpt index 44ae1f1cde..e205891fcb 100644 --- a/ext/xml/tests/bug72085.phpt +++ b/ext/xml/tests/bug72085.phpt @@ -10,65 +10,43 @@ $var1 = xml_parser_create_ns(); xml_set_element_handler($var1, new Exception(""), 4096); xml_parse($var1, str_repeat("<a>", 10)); ?> -===DONE=== --EXPECTF-- -Warning: Invalid callback Exception in %s%ebug72085.php:%d -Stack trace: -#0 {main}, no array or string given in %s%ebug72085.php on line %d +Warning: Invalid callback Exception::__invoke, no array or string given in %s on line %d -Warning: xml_parse(): Unable to call handler in %s%ebug72085.php on line %d +Warning: xml_parse(): Unable to call handler in %s on line %d -Warning: Invalid callback Exception in %s%ebug72085.php:%d -Stack trace: -#0 {main}, no array or string given in %s%ebug72085.php on line %d +Warning: Invalid callback Exception::__invoke, no array or string given in %s on line %d -Warning: xml_parse(): Unable to call handler in %s%ebug72085.php on line %d +Warning: xml_parse(): Unable to call handler in %s on line %d -Warning: Invalid callback Exception in %s%ebug72085.php:%d -Stack trace: -#0 {main}, no array or string given in %s%ebug72085.php on line %d +Warning: Invalid callback Exception::__invoke, no array or string given in %s on line %d -Warning: xml_parse(): Unable to call handler in %s%ebug72085.php on line %d +Warning: xml_parse(): Unable to call handler in %s on line %d -Warning: Invalid callback Exception in %s%ebug72085.php:%d -Stack trace: -#0 {main}, no array or string given in %s%ebug72085.php on line %d +Warning: Invalid callback Exception::__invoke, no array or string given in %s on line %d -Warning: xml_parse(): Unable to call handler in %s%ebug72085.php on line %d +Warning: xml_parse(): Unable to call handler in %s on line %d -Warning: Invalid callback Exception in %s%ebug72085.php:%d -Stack trace: -#0 {main}, no array or string given in %s%ebug72085.php on line %d +Warning: Invalid callback Exception::__invoke, no array or string given in %s on line %d -Warning: xml_parse(): Unable to call handler in %s%ebug72085.php on line %d +Warning: xml_parse(): Unable to call handler in %s on line %d -Warning: Invalid callback Exception in %s%ebug72085.php:%d -Stack trace: -#0 {main}, no array or string given in %s%ebug72085.php on line %d +Warning: Invalid callback Exception::__invoke, no array or string given in %s on line %d -Warning: xml_parse(): Unable to call handler in %s%ebug72085.php on line %d +Warning: xml_parse(): Unable to call handler in %s on line %d -Warning: Invalid callback Exception in %s%ebug72085.php:%d -Stack trace: -#0 {main}, no array or string given in %s%ebug72085.php on line %d +Warning: Invalid callback Exception::__invoke, no array or string given in %s on line %d -Warning: xml_parse(): Unable to call handler in %s%ebug72085.php on line %d +Warning: xml_parse(): Unable to call handler in %s on line %d -Warning: Invalid callback Exception in %s%ebug72085.php:%d -Stack trace: -#0 {main}, no array or string given in %s%ebug72085.php on line %d +Warning: Invalid callback Exception::__invoke, no array or string given in %s on line %d -Warning: xml_parse(): Unable to call handler in %s%ebug72085.php on line %d +Warning: xml_parse(): Unable to call handler in %s on line %d -Warning: Invalid callback Exception in %s%ebug72085.php:%d -Stack trace: -#0 {main}, no array or string given in %s%ebug72085.php on line %d +Warning: Invalid callback Exception::__invoke, no array or string given in %s on line %d -Warning: xml_parse(): Unable to call handler in %s%ebug72085.php on line %d +Warning: xml_parse(): Unable to call handler in %s on line %d -Warning: Invalid callback Exception in %s%ebug72085.php:%d -Stack trace: -#0 {main}, no array or string given in %s%ebug72085.php on line %d +Warning: Invalid callback Exception::__invoke, no array or string given in %s on line %d -Warning: xml_parse(): Unable to call handler in %s%ebug72085.php on line %d -===DONE=== +Warning: xml_parse(): Unable to call handler in %s on line %d diff --git a/ext/xml/tests/bug72099.phpt b/ext/xml/tests/bug72099.phpt index b32de02b24..6d6c20e950 100644 --- a/ext/xml/tests/bug72099.phpt +++ b/ext/xml/tests/bug72099.phpt @@ -12,6 +12,7 @@ $var3=[]; $var4=[]; xml_parse_into_struct($var1, $var2, $var3, $var4); var_dump($var3); +?> --EXPECT-- array(0) { } diff --git a/ext/xml/tests/bug72714.phpt b/ext/xml/tests/bug72714.phpt index 7b44e1fd11..08fff0c06b 100644 --- a/ext/xml/tests/bug72714.phpt +++ b/ext/xml/tests/bug72714.phpt @@ -27,9 +27,7 @@ function parse($tagstart) { parse(3015809298423721); parse(20); ?> -===DONE=== --EXPECTF-- -Notice: xml_parser_set_option(): tagstart ignored, because it is out of range in %s%ebug72714.php on line %d +Warning: xml_parser_set_option(): tagstart ignored, because it is out of range in %s on line %d string(9) "NS1:TOTAL" string(0) "" -===DONE=== diff --git a/ext/xml/tests/bug72793.phpt b/ext/xml/tests/bug72793.phpt new file mode 100644 index 0000000000..edbbaed884 --- /dev/null +++ b/ext/xml/tests/bug72793.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #72793: xml_parser_free leaks mem when execute xml_set_object +--SKIPIF-- +<?php include("skipif.inc"); ?> +--FILE-- +<?php + +class xml { + var $parser; + + function __construct() + { + $this->parser = xml_parser_create(); + xml_set_object($this->parser, $this); + } + + function parse($data) + { + xml_parse($this->parser, $data); + } + + function free(){ + xml_parser_free($this->parser); + } +} + +$xml_test = '<?xml version="1.0" encoding="utf-8"?><test></test>'; +$xml_parser = new xml(); +$xml_parser->parse($xml_test); +$xml_parser->free(); + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/xml/tests/bug76874.phpt b/ext/xml/tests/bug76874.phpt new file mode 100644 index 0000000000..ec0caae706 --- /dev/null +++ b/ext/xml/tests/bug76874.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #76874: xml_parser_free() should never leak memory +--SKIPIF-- +<?php include("skipif.inc"); ?> +--FILE-- +<?php + +class c +{ + private $xml; + private $test; + + public function test() + { + $this->xml = xml_parser_create(); + xml_set_character_data_handler($this->xml, array(&$this, 'handle_cdata')); + xml_parser_free($this->xml); + } + + public function handle_cdata(&$parser, $data) + { + } +} + +$object = new c(); +$object->test(); + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/xml/tests/bug78563.phpt b/ext/xml/tests/bug78563.phpt new file mode 100644 index 0000000000..a69b7b539a --- /dev/null +++ b/ext/xml/tests/bug78563.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #78563: parsers should not be clonable +--SKIPIF-- +<?php include("skipif.inc"); ?> +--FILE-- +<?php + +$parser = xml_parser_create(); +clone $parser; + +?> +===DONE=== +--EXPECTF-- +Fatal error: Uncaught Error: Trying to clone an uncloneable object of class XMLParser in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/ext/xml/tests/bug78563_final.phpt b/ext/xml/tests/bug78563_final.phpt new file mode 100644 index 0000000000..e8a819f85b --- /dev/null +++ b/ext/xml/tests/bug78563_final.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #78563: parsers should not be extendable +--SKIPIF-- +<?php include("skipif.inc"); ?> +--FILE-- +<?php + +class Dummy extends Xmlparser { + +} + +?> +===DONE=== +--EXPECTF-- +Fatal error: Class Dummy may not inherit from final class (XMLParser) in %s on line %d diff --git a/ext/xml/tests/bug78563_serialize.phpt b/ext/xml/tests/bug78563_serialize.phpt new file mode 100644 index 0000000000..05171dc79e --- /dev/null +++ b/ext/xml/tests/bug78563_serialize.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #78563: parsers should not be serializable +--SKIPIF-- +<?php include("skipif.inc"); ?> +--FILE-- +<?php + +$parser = xml_parser_create(); +serialize($parser); + +?> +===DONE=== +--EXPECTF-- +Fatal error: Uncaught Exception: Serialization of 'XMLParser' is not allowed in %s:%d +Stack trace: +#0 %s(%d): serialize(Object(XMLParser)) +#1 {main} + thrown in %s on line %d diff --git a/ext/xml/tests/bug79922.phpt b/ext/xml/tests/bug79922.phpt deleted file mode 100644 index e578a5d2c4..0000000000 --- a/ext/xml/tests/bug79922.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -Bug #79922 (Crash after multiple calls to xml_parser_free()) ---SKIPIF-- -<?php -if (!extension_loaded('xml')) die('skip xml extension not available'); -?> ---FILE-- -<?php -$c=xml_parser_create_ns(); -$a=xml_parser_free($c); -$a=xml_parser_free($c); -$c=0; -var_dump($a); -?> ---EXPECTF-- -Warning: xml_parser_free(): supplied resource is not a valid XML Parser resource in %s on line %d -bool(false) diff --git a/ext/xml/tests/xml001.phpt b/ext/xml/tests/xml001.phpt index e859a4bbcb..2d8fe54041 100644 --- a/ext/xml/tests/xml001.phpt +++ b/ext/xml/tests/xml001.phpt @@ -22,54 +22,54 @@ if (!($fp = @fopen("xmltest.xml", "r"))) { } while ($data = fread($fp, 4096)) { - if (!xml_parse($xml_parser, $data, feof($fp))) { - die(sprintf("XML error: %s at line %d\n", - xml_error_string(xml_get_error_code($xml_parser)), - xml_get_current_line_number($xml_parser))); - } + if (!xml_parse($xml_parser, $data, feof($fp))) { + die(sprintf("XML error: %s at line %d\n", + xml_error_string(xml_get_error_code($xml_parser)), + xml_get_current_line_number($xml_parser))); + } } print "parse complete\n"; xml_parser_free($xml_parser); function startElement($parser, $name, $attribs) { - print '{'.$name; - if (sizeof($attribs)) { + print '{'.$name; + if (sizeof($attribs)) { foreach ($attribs as $k => $v) { - print " $k=\"$v\""; - } - } - print '}'; + print " $k=\"$v\""; + } + } + print '}'; } function endElement($parser, $name) { - print '{/'.$name.'}'; + print '{/'.$name.'}'; } function characterData($parser, $data) { - print '{CDATA['.$data.']}'; + print '{CDATA['.$data.']}'; } function PIHandler($parser, $target, $data) { - print '{PI['.$target.','.$data.']}'; + print '{PI['.$target.','.$data.']}'; } function defaultHandler($parser, $data) { - if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") { - print '{ENTREF['.$data.']}'; - } else { - print '{?['.$data.']}'; - } + if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") { + print '{ENTREF['.$data.']}'; + } else { + print '{?['.$data.']}'; + } } function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId, $publicId) { - print '{EXTENTREF['.$openEntityNames.','.$base.','.$systemId.','.$publicId."]}\n"; - return true; + print '{EXTENTREF['.$openEntityNames.','.$base.','.$systemId.','.$publicId."]}\n"; + return true; } ?> diff --git a/ext/xml/tests/xml002.phpt b/ext/xml/tests/xml002.phpt index e183fa4ae3..27a920cedd 100644 --- a/ext/xml/tests/xml002.phpt +++ b/ext/xml/tests/xml002.phpt @@ -11,41 +11,41 @@ chdir(__DIR__); class myclass { - function startElement($parser, $name, $attribs) - { - print '{'.$name; - if (sizeof($attribs)) { + function startElement($parser, $name, $attribs) + { + print '{'.$name; + if (sizeof($attribs)) { foreach ($attribs as $k => $v) { - print " $k=\"$v\""; - } - } - print '}'; - } - function endElement($parser, $name) - { - print '{/'.$name.'}'; - } - function characterData($parser, $data) - { - print '{CDATA['.$data.']}'; - } - function PIHandler($parser, $target, $data) - { - print '{PI['.$target.','.$data.']}'; - } - function defaultHandler($parser, $data) - { - if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") { - print '{ENTREF['.$data.']}'; - } else { - print '{?['.$data.']}'; - } - } - function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId, $publicId) - { - print '{EXTENTREF['.$openEntityNames.','.$base.','.$systemId.','.$publicId."]}\n"; - return true; - } + print " $k=\"$v\""; + } + } + print '}'; + } + function endElement($parser, $name) + { + print '{/'.$name.'}'; + } + function characterData($parser, $data) + { + print '{CDATA['.$data.']}'; + } + function PIHandler($parser, $target, $data) + { + print '{PI['.$target.','.$data.']}'; + } + function defaultHandler($parser, $data) + { + if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") { + print '{ENTREF['.$data.']}'; + } else { + print '{?['.$data.']}'; + } + } + function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId, $publicId) + { + print '{EXTENTREF['.$openEntityNames.','.$base.','.$systemId.','.$publicId."]}\n"; + return true; + } } $xml_parser = xml_parser_create(); @@ -60,15 +60,15 @@ xml_set_external_entity_ref_handler($xml_parser, array($obj, "externalEntityRefHandler")); if (!($fp = @fopen("xmltest.xml", "r"))) { - die("could not open XML input"); + die("could not open XML input"); } while ($data = fread($fp, 4096)) { - if (!xml_parse($xml_parser, $data, feof($fp))) { - die(sprintf("XML error: %s at line %d\n", - xml_error_string(xml_get_error_code($xml_parser)), - xml_get_current_line_number($xml_parser))); - } + if (!xml_parse($xml_parser, $data, feof($fp))) { + die(sprintf("XML error: %s at line %d\n", + xml_error_string(xml_get_error_code($xml_parser)), + xml_get_current_line_number($xml_parser))); + } } print "parse complete\n"; xml_parser_free($xml_parser); diff --git a/ext/xml/tests/xml003.phpt b/ext/xml/tests/xml003.phpt index fb4cbbd29e..08db287c18 100644 --- a/ext/xml/tests/xml003.phpt +++ b/ext/xml/tests/xml003.phpt @@ -11,41 +11,41 @@ chdir(__DIR__); class myclass { - function startElement($parser, $name, $attribs) - { - print '{'.$name; - if (sizeof($attribs)) { + function startElement($parser, $name, $attribs) + { + print '{'.$name; + if (sizeof($attribs)) { foreach ($attribs as $k => $v) { - print " $k=\"$v\""; - } - } - print '}'; - } - function endElement($parser, $name) - { - print '{/'.$name.'}'; - } - function characterData($parser, $data) - { - print '{CDATA['.$data.']}'; - } - function PIHandler($parser, $target, $data) - { - print '{PI['.$target.','.$data.']}'; - } - function defaultHandler($parser, $data) - { - if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") { - print '{ENTREF['.$data.']}'; - } else { - print '{?['.$data.']}'; - } - } - function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId, $publicId) - { - print '{EXTENTREF['.$openEntityNames.','.$base.','.$systemId.','.$publicId."]}\n"; - return true; - } + print " $k=\"$v\""; + } + } + print '}'; + } + function endElement($parser, $name) + { + print '{/'.$name.'}'; + } + function characterData($parser, $data) + { + print '{CDATA['.$data.']}'; + } + function PIHandler($parser, $target, $data) + { + print '{PI['.$target.','.$data.']}'; + } + function defaultHandler($parser, $data) + { + if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") { + print '{ENTREF['.$data.']}'; + } else { + print '{?['.$data.']}'; + } + } + function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId, $publicId) + { + print '{EXTENTREF['.$openEntityNames.','.$base.','.$systemId.','.$publicId."]}\n"; + return true; + } } $xml_parser = xml_parser_create(); @@ -59,15 +59,15 @@ xml_set_default_handler($xml_parser, "defaultHandler"); xml_set_external_entity_ref_handler($xml_parser, "externalEntityRefHandler"); if (!($fp = @fopen("xmltest.xml", "r"))) { - die("could not open XML input"); + die("could not open XML input"); } while ($data = fread($fp, 4096)) { - if (!xml_parse($xml_parser, $data, feof($fp))) { - die(sprintf("XML error: %s at line %d\n", - xml_error_string(xml_get_error_code($xml_parser)), - xml_get_current_line_number($xml_parser))); - } + if (!xml_parse($xml_parser, $data, feof($fp))) { + die(sprintf("XML error: %s at line %d\n", + xml_error_string(xml_get_error_code($xml_parser)), + xml_get_current_line_number($xml_parser))); + } } print "parse complete\n"; xml_parser_free($xml_parser); diff --git a/ext/xml/tests/xml004.phpt b/ext/xml/tests/xml004.phpt index 1e545db2a1..3d5adaa56b 100644 --- a/ext/xml/tests/xml004.phpt +++ b/ext/xml/tests/xml004.phpt @@ -11,7 +11,7 @@ xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); xml_set_element_handler($xp, "start_element", "end_element"); $fp = fopen("xmltest.xml", "r"); while ($data = fread($fp, 4096)) { - xml_parse($xp, $data, feof($fp)); + xml_parse($xp, $data, feof($fp)); } xml_parser_free($xp); $xp = xml_parser_create(); @@ -19,24 +19,24 @@ xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, true); xml_set_element_handler($xp, "start_element", "end_element"); $fp = fopen("xmltest.xml", "r"); while ($data = fread($fp, 4096)) { - xml_parse($xp, $data, feof($fp)); + xml_parse($xp, $data, feof($fp)); } xml_parser_free($xp); function start_element($xp, $elem, $attribs) { - print "<$elem"; - if (sizeof($attribs)) { + print "<$elem"; + if (sizeof($attribs)) { foreach ($attribs as $k => $v) { - print " $k=\"$v\""; - } - } - print ">\n"; + print " $k=\"$v\""; + } + } + print ">\n"; } function end_element($xp, $elem) { - print "</$elem>\n"; + print "</$elem>\n"; } ?> --EXPECT-- diff --git a/ext/xml/tests/xml007.phpt b/ext/xml/tests/xml007.phpt index f19f0389b6..6389c7fa6e 100644 --- a/ext/xml/tests/xml007.phpt +++ b/ext/xml/tests/xml007.phpt @@ -5,19 +5,19 @@ xml_parse_into_struct/umlauts in tags include("skipif.inc"); if(strtoupper("äöüß") != "ÄÖÜß") { - die("skip strtoupper on non-ascii not supported on this platform"); + die("skip strtoupper on non-ascii not supported on this platform"); } ?> --FILE-- <?php function startHandler($parser,$tag,$attr) { - var_dump($tag,$attr); + var_dump($tag,$attr); } function endHandler($parser,$tag) { - var_dump($tag); + var_dump($tag); } $xmldata = '<?xml version="1.0" encoding="ISO-8859-1"?><äöü üäß="Üäß">ÄÖÜ</äöü>'; diff --git a/ext/xml/tests/xml009.phpt b/ext/xml/tests/xml009.phpt index 84b89bb488..8a33a4e715 100644 --- a/ext/xml/tests/xml009.phpt +++ b/ext/xml/tests/xml009.phpt @@ -3,12 +3,12 @@ XML parser test, default namespaces --SKIPIF-- <?php require_once("skipif.inc"); -if (! @xml_parser_create_ns('ISO-8859-1')) { die("skip xml_parser_create_ns is not supported on this plattform");} +if (! @xml_parser_create_ns('ISO-8859-1')) { die("skip xml_parser_create_ns is not supported on this platform");} ?> --FILE-- <?php function start_elem($parser,$name,$attribs) { - var_dump($name); + var_dump($name); } function end_elem() { @@ -17,7 +17,7 @@ function end_elem() $xml = <<<HERE <a xmlns="http://example.com/foo" xmlns:bar="http://example.com/bar" - xmlns:baz="http://example.com/baz"> + xmlns:baz="http://example.com/baz"> <bar:b /> <bar:c xmlns:bar="http://example.com/foo"/> </a> diff --git a/ext/xml/tests/xml010.phpt b/ext/xml/tests/xml010.phpt index 511129c699..69e8469fa6 100644 --- a/ext/xml/tests/xml010.phpt +++ b/ext/xml/tests/xml010.phpt @@ -3,12 +3,12 @@ XML parser test, attributes --SKIPIF-- <?php require_once("skipif.inc"); -if (! @xml_parser_create_ns('ISO-8859-1')) { die("skip xml_parser_create_ns is not supported on this plattform");} +if (! @xml_parser_create_ns('ISO-8859-1')) { die("skip xml_parser_create_ns is not supported on this platform");} ?> --FILE-- <?php function start_elem($parser,$name,$attribs) { - print "$name "; + print "$name "; foreach($attribs as $key => $value) { print "$key = $value "; diff --git a/ext/xml/tests/xml_closures_001.phpt b/ext/xml/tests/xml_closures_001.phpt index da9d849da5..c1f91d50d5 100644 --- a/ext/xml/tests/xml_closures_001.phpt +++ b/ext/xml/tests/xml_closures_001.phpt @@ -8,18 +8,18 @@ chdir(__DIR__); $start_element = function ($xp, $elem, $attribs) { - print "<$elem"; - if (sizeof($attribs)) { + print "<$elem"; + if (sizeof($attribs)) { foreach ($attribs as $k => $v) { - print " $k=\"$v\""; - } - } - print ">\n"; + print " $k=\"$v\""; + } + } + print ">\n"; }; $end_element = function ($xp, $elem) { - print "</$elem>\n"; + print "</$elem>\n"; }; $xp = xml_parser_create(); @@ -27,7 +27,7 @@ xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); xml_set_element_handler($xp, $start_element, $end_element); $fp = fopen("xmltest.xml", "r"); while ($data = fread($fp, 4096)) { - xml_parse($xp, $data, feof($fp)); + xml_parse($xp, $data, feof($fp)); } xml_parser_free($xp); diff --git a/ext/xml/tests/xml_error_string_basic.phpt b/ext/xml/tests/xml_error_string_basic.phpt new file mode 100644 index 0000000000..e72fa68bd1 --- /dev/null +++ b/ext/xml/tests/xml_error_string_basic.phpt @@ -0,0 +1,38 @@ +--TEST-- +xml_error_string() - Basic test on 5 error codes +--SKIPIF-- +<?php +if (!extension_loaded('xml')) { + exit('Skip - XML extension not loaded'); +} +?> +--FILE-- +<?php +$xmls = array( + '<?xml version="1.0"?><element>', + '<?xml>', + '<?xml version="dummy">', + '<?xml?>', + '<?xml version="1.0"?><elem></element>', +); + +foreach ($xmls as $xml) { + $xml_parser = xml_parser_create(); + if (!xml_parse($xml_parser, $xml, true)) { + var_dump(xml_get_error_code($xml_parser)); + var_dump(xml_error_string(xml_get_error_code($xml_parser))); + } + xml_parser_free($xml_parser); +} +?> +--EXPECT-- +int(5) +string(20) "Invalid document end" +int(47) +string(35) "Processing Instruction not finished" +int(57) +string(28) "XML declaration not finished" +int(64) +string(17) "Reserved XML Name" +int(76) +string(14) "Mismatched tag" diff --git a/ext/xml/tests/xml_parse_into_struct_variation.phpt b/ext/xml/tests/xml_parse_into_struct_variation.phpt index 28c7acf9c3..a03b86ac8a 100644 --- a/ext/xml/tests/xml_parse_into_struct_variation.phpt +++ b/ext/xml/tests/xml_parse_into_struct_variation.phpt @@ -3,17 +3,11 @@ Test xml_parse_into_struct() function : variation --SKIPIF-- <?php if (!extension_loaded("xml")) { - print "skip - XML extension not loaded"; + print "skip - XML extension not loaded"; } ?> --FILE-- <?php -/* Prototype : proto int xml_parse_into_struct(resource parser, string data, array &struct, array &index) - * Description: Parsing a XML document - * Source code: ext/xml/xml.c - * Alias to functions: - */ - echo "*** Testing xml_parse_into_struct() : variation ***\n"; $simple = "<main><para><note>simple note</note></para><para><note>simple note</note></para></main>"; diff --git a/ext/xml/tests/xml_parser_get_option_variation4.phpt b/ext/xml/tests/xml_parser_get_option_variation4.phpt new file mode 100644 index 0000000000..0a1410608b --- /dev/null +++ b/ext/xml/tests/xml_parser_get_option_variation4.phpt @@ -0,0 +1,22 @@ +--TEST-- +xml_parser_get_option() - Test parameter not set +--SKIPIF-- +<?php +if (!extension_loaded('xml')) { + exit('Skip - XML extension not loaded'); +} +?> +--FILE-- +<?php + +$xmlParser = xml_parser_create(); + +try { + xml_parser_get_option ($xmlParser, 42); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +?> +--EXPECT-- +xml_parser_get_option(): Argument #2 ($option) must be a PHP_XML_OPTION_* constant diff --git a/ext/xml/tests/xml_parser_set_option_basic.phpt b/ext/xml/tests/xml_parser_set_option_basic.phpt index 48d91eafb6..cae9ed7146 100644 --- a/ext/xml/tests/xml_parser_set_option_basic.phpt +++ b/ext/xml/tests/xml_parser_set_option_basic.phpt @@ -3,17 +3,11 @@ Test xml_set_notation_decl_handler function : basic --SKIPIF-- <?php if (!extension_loaded("xml")) { - print "skip - XML extension not loaded"; + print "skip - XML extension not loaded"; } ?> --FILE-- <?php -/* Prototype : proto bool xml_set_notation_decl_handler ( resource $parser , callback $handler ) - * Description: Sets the notation declaration handler function for the XML parser. - * Source code: ext/xml/xml.c - * Alias to functions: - */ - echo "Simple testcase for xml_parser_get_option() function\n"; $parser = xml_parser_create_ns(); diff --git a/ext/xml/tests/xml_parser_set_option_variation3.phpt b/ext/xml/tests/xml_parser_set_option_variation3.phpt index 836ee7a469..a6b3a9b6ec 100644 --- a/ext/xml/tests/xml_parser_set_option_variation3.phpt +++ b/ext/xml/tests/xml_parser_set_option_variation3.phpt @@ -3,19 +3,12 @@ Test xml_parser_set_option() function : usage variations --SKIPIF-- <?php if (!extension_loaded("xml")) { - print "skip - XML extension not loaded"; + print "skip - XML extension not loaded"; } ?> --FILE-- <?php -/* Prototype : proto int xml_parser_set_option(resource parser, int option, mixed value) - * Description: Set options in an XML parser - * Source code: ext/xml/xml.c - * Alias to functions: - */ - echo "*** Testing xml_parser_set_option() : usage variations ***\n"; -error_reporting(E_ALL & ~E_NOTICE); class aClass { function __toString() { @@ -79,20 +72,14 @@ $values = array( // resource data $fp, - - // undefined data - $undefined_var, - - // unset data - $unset_var, ); // loop through each element of the array for value foreach($values as $value) { - echo @"\nArg value $value \n"; - var_dump( xml_parser_set_option($parser, $option, $value) ); -}; + echo @"\nArg value $value \n"; + var_dump(xml_parser_set_option($parser, $option, $value)); +} fclose($fp); xml_parser_free($parser); @@ -174,14 +161,10 @@ Arg value string bool(true) Arg value Some Ascii Data -bool(true) -Arg value Resource id %s +Warning: Object of class aClass could not be converted to int in %s on line %d bool(true) -Arg value -bool(true) - -Arg value +Arg value Resource id %s bool(true) Done diff --git a/ext/xml/tests/xml_parser_set_option_variation4.phpt b/ext/xml/tests/xml_parser_set_option_variation4.phpt index da59a7eb9b..b1c96b8d33 100644 --- a/ext/xml/tests/xml_parser_set_option_variation4.phpt +++ b/ext/xml/tests/xml_parser_set_option_variation4.phpt @@ -15,11 +15,14 @@ if (!extension_loaded("xml")) { $xmlParser = xml_parser_create(); var_dump(xml_parser_set_option($xmlParser, XML_OPTION_SKIP_WHITE, 1)); -var_dump(xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, 'Invalid Encoding')); + +try { + xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, 'Invalid Encoding'); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} ?> ---EXPECTF-- +--EXPECT-- bool(true) - -Warning: xml_parser_set_option(): Unsupported target encoding "Invalid Encoding" in %s on line %d -bool(false) +xml_parser_set_option(): Argument #3 ($value) is not a supported target encoding diff --git a/ext/xml/tests/xml_parser_set_option_variation5.phpt b/ext/xml/tests/xml_parser_set_option_variation5.phpt new file mode 100644 index 0000000000..e637e692a8 --- /dev/null +++ b/ext/xml/tests/xml_parser_set_option_variation5.phpt @@ -0,0 +1,22 @@ +--TEST-- +xml_parser_set_option() - Test invalid parameter +--SKIPIF-- +<?php +if (!extension_loaded('xml')) { + exit('Skip - XML extension not loaded'); +} +?> +--FILE-- +<?php + +$xmlParser = xml_parser_create(); + +try { + xml_parser_set_option($xmlParser, 42, 1); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +?> +--EXPECT-- +xml_parser_set_option(): Argument #2 ($option) must be a PHP_XML_OPTION_* constant diff --git a/ext/xml/tests/xml_set_notation_decl_handler_basic.phpt b/ext/xml/tests/xml_set_notation_decl_handler_basic.phpt index a4ea86375e..aa37b84a55 100644 --- a/ext/xml/tests/xml_set_notation_decl_handler_basic.phpt +++ b/ext/xml/tests/xml_set_notation_decl_handler_basic.phpt @@ -3,38 +3,32 @@ Test xml_set_notation_decl_handler function : basic --SKIPIF-- <?php if (!extension_loaded("xml")) { - print "skip - XML extension not loaded"; + print "skip - XML extension not loaded"; } ?> --FILE-- <?php -/* Prototype : proto bool xml_set_notation_decl_handler ( resource $parser , callback $handler ) - * Description: Sets the notation declaration handler function for the XML parser. - * Source code: ext/xml/xml.c - * Alias to functions: - */ - class XML_Parser { function unparsed_entity_decl_handler($parser, $entity_name, $base, $system_ID, $public_ID, $notation_name) - { - echo "unparsed_entity_decl_handler called\n"; - echo "...Entity name=" . $entity_name . "\n"; - echo "...Base=" . $base . "\n"; - echo "...System ID=" . $system_ID . "\n"; - echo "...Public ID=" . $public_ID . "\n"; - echo "...Notation name=" . $notation_name . "\n"; - } + { + echo "unparsed_entity_decl_handler called\n"; + echo "...Entity name=" . $entity_name . "\n"; + echo "...Base=" . $base . "\n"; + echo "...System ID=" . $system_ID . "\n"; + echo "...Public ID=" . $public_ID . "\n"; + echo "...Notation name=" . $notation_name . "\n"; + } - function notation_decl_handler($parser, $name, $base, $system_ID,$public_ID) - { - echo "notation_decl_handler called\n"; - echo "...Name=" . $name . "\n"; - echo "...Base=" . $base . "\n"; - echo "...System ID=" . $system_ID . "\n"; - echo "...Public ID=" . $public_ID . "\n"; - } + function notation_decl_handler($parser, $name, $base, $system_ID,$public_ID) + { + echo "notation_decl_handler called\n"; + echo "...Name=" . $name . "\n"; + echo "...Base=" . $base . "\n"; + echo "...System ID=" . $system_ID . "\n"; + echo "...Public ID=" . $public_ID . "\n"; + } function parse($data) { @@ -54,8 +48,8 @@ $xml = <<<HERE <!NOTATION AUSDATE SYSTEM "http://www.schema.net/ausdate.not"> <!NOTATION ISODATE SYSTEM "http://www.schema.net/isodate.not"> <!ENTITY testUS SYSTEM "test_usdate.xml" NDATA USDATE> - <!ENTITY testAUS SYSTEM "test_ausdate.xml" NDATA AUSDATE> - <!ENTITY testISO SYSTEM "test_isodate_xml" NDATA ISODATE>]> + <!ENTITY testAUS SYSTEM "test_ausdate.xml" NDATA AUSDATE> + <!ENTITY testISO SYSTEM "test_isodate_xml" NDATA ISODATE>]> ]> HERE; diff --git a/ext/xml/tests/xml_set_processing_instruction_handler_basic.phpt b/ext/xml/tests/xml_set_processing_instruction_handler_basic.phpt index cd5dda7763..dc9efe278b 100644 --- a/ext/xml/tests/xml_set_processing_instruction_handler_basic.phpt +++ b/ext/xml/tests/xml_set_processing_instruction_handler_basic.phpt @@ -3,25 +3,19 @@ Test xml_set_processing_instruction_handler function : basic --SKIPIF-- <?php if (!extension_loaded("xml")) { - print "skip - XML extension not loaded"; + print "skip - XML extension not loaded"; } ?> --FILE-- <?php -/* Prototype : proto bool xml_set_processing_instruction_handler ( resource $parser , callback $handler ) - * Description: Sets the processing instruction (PI) handler function for the XML parser. - * Source code: ext/xml/xml.c - * Alias to functions: - */ - class XML_Parser { function PIHandler($parser, $target, $data) - { - echo "Target: " . $target. "\n"; - echo "Data: " . $data . "\n"; - } + { + echo "Target: " . $target. "\n"; + echo "Data: " . $data . "\n"; + } function parse($data) { diff --git a/ext/xml/tests/xml_set_start_namespace_decl_handler_basic.phpt b/ext/xml/tests/xml_set_start_namespace_decl_handler_basic.phpt index 8ee12e77cd..ba27eec9f5 100644 --- a/ext/xml/tests/xml_set_start_namespace_decl_handler_basic.phpt +++ b/ext/xml/tests/xml_set_start_namespace_decl_handler_basic.phpt @@ -3,17 +3,11 @@ Test xml_set_start_namespace_decl_handler function: basic --SKIPIF-- <?php if (!extension_loaded("xml")) { - print "skip - XML extension not loaded"; + print "skip - XML extension not loaded"; } ?> --FILE-- <?php -/* Prototype : bool xml_set_start_namespace_decl_handler ( resource $parser , callback $handler ) - * Description: Set up start namespace declaration handler. - * Source code: ext/xml/xml.c - * Alias to functions: - */ - $xml = <<<HERE <aw1:book xmlns:aw1="http://www.somewhere.com/namespace1" xmlns:aw2="file:/DTD/somewhere.dtd"> @@ -34,14 +28,14 @@ xml_parser_free( $parser ); echo "Done\n"; function Namespace_Start_Handler( $parser, $prefix, $uri ) { - echo "Namespace_Start_Handler called\n"; - echo "...Prefix: ". $prefix . "\n"; - echo "...Uri: ". $uri . "\n"; + echo "Namespace_Start_Handler called\n"; + echo "...Prefix: ". $prefix . "\n"; + echo "...Uri: ". $uri . "\n"; } function Namespace_End_Handler($parser, $prefix) { - echo "Namespace_End_Handler called\n"; - echo "...Prefix: ". $prefix . "\n\n"; + echo "Namespace_End_Handler called\n"; + echo "...Prefix: ". $prefix . "\n\n"; } function DefaultHandler( $parser, $data ) { diff --git a/ext/xml/xml.c b/ext/xml/xml.c index af3431daa4..3064545739 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | @@ -28,8 +26,9 @@ #include "ext/standard/php_string.h" #include "ext/standard/info.h" #include "ext/standard/html.h" +#include "zend_interfaces.h" -#if HAVE_XML +#ifdef HAVE_XML #include "php_xml.h" # include "ext/standard/head.h" @@ -37,6 +36,8 @@ #include "ext/libxml/php_libxml.h" #endif +#include "xml_arginfo.h" + /* Short-term TODO list: * - Implement XML_ExternalEntityParserCreate() * - XML_SetCommentHandler @@ -66,7 +67,15 @@ typedef struct { XML_Parser parser; XML_Char *target_encoding; + /* Reference to the object itself, for convenience. + * It is not owned, do not release it. */ zval index; + + /* We return a pointer to these zvals in get_gc(), so it's + * important that a) they are adjacent b) object is the first + * and c) the number of zvals is kept up to date. */ +#define XML_PARSER_NUM_ZVALS 12 + zval object; zval startElementHandler; zval endElementHandler; zval characterDataHandler; @@ -91,8 +100,6 @@ typedef struct { zend_function *startNamespaceDeclPtr; zend_function *endNamespaceDeclPtr; - zval object; - zval data; zval info; int level; @@ -105,6 +112,8 @@ typedef struct { int isparsing; XML_Char *baseURI; + + zend_object std; } xml_parser; @@ -135,37 +144,20 @@ ZEND_GET_MODULE(xml) #define SKIP_TAGSTART(str) ((str) + (parser->toffset > (int)strlen(str) ? strlen(str) : parser->toffset)) +static zend_class_entry *xml_parser_ce; +static zend_object_handlers xml_parser_object_handlers; /* {{{ function prototypes */ PHP_MINIT_FUNCTION(xml); PHP_MINFO_FUNCTION(xml); static PHP_GINIT_FUNCTION(xml); -PHP_FUNCTION(xml_parser_create); -PHP_FUNCTION(xml_parser_create_ns); -PHP_FUNCTION(xml_set_object); -PHP_FUNCTION(xml_set_element_handler); -PHP_FUNCTION(xml_set_character_data_handler); -PHP_FUNCTION(xml_set_processing_instruction_handler); -PHP_FUNCTION(xml_set_default_handler); -PHP_FUNCTION(xml_set_unparsed_entity_decl_handler); -PHP_FUNCTION(xml_set_notation_decl_handler); -PHP_FUNCTION(xml_set_external_entity_ref_handler); -PHP_FUNCTION(xml_set_start_namespace_decl_handler); -PHP_FUNCTION(xml_set_end_namespace_decl_handler); -PHP_FUNCTION(xml_parse); -PHP_FUNCTION(xml_get_error_code); -PHP_FUNCTION(xml_error_string); -PHP_FUNCTION(xml_get_current_line_number); -PHP_FUNCTION(xml_get_current_column_number); -PHP_FUNCTION(xml_get_current_byte_index); -PHP_FUNCTION(xml_parser_free); -PHP_FUNCTION(xml_parser_set_option); -PHP_FUNCTION(xml_parser_get_option); -PHP_FUNCTION(xml_parse_into_struct); +static zend_object *xml_parser_create_object(zend_class_entry *class_type); +static void xml_parser_free_obj(zend_object *object); +static HashTable *xml_parser_get_gc(zend_object *object, zval **table, int *n); +static zend_function *xml_parser_get_constructor(zend_object *object); static zend_string *xml_utf8_decode(const XML_Char *, size_t, const XML_Char *); -static void xml_parser_dtor(zend_resource *rsrc); static void xml_set_handler(zval *, zval *); inline static unsigned short xml_encode_iso_8859_1(unsigned char); inline static char xml_decode_iso_8859_1(unsigned short); @@ -190,141 +182,6 @@ void _xml_startNamespaceDeclHandler(void *, const XML_Char *, const XML_Char *); void _xml_endNamespaceDeclHandler(void *, const XML_Char *); /* }}} */ -/* {{{ extension definition structures */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_create, 0, 0, 0) - ZEND_ARG_INFO(0, encoding) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_create_ns, 0, 0, 0) - ZEND_ARG_INFO(0, encoding) - ZEND_ARG_INFO(0, sep) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_object, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, obj) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_element_handler, 0, 0, 3) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, shdl) - ZEND_ARG_INFO(0, ehdl) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_character_data_handler, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, hdl) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_processing_instruction_handler, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, hdl) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_default_handler, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, hdl) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_unparsed_entity_decl_handler, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, hdl) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_notation_decl_handler, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, hdl) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_external_entity_ref_handler, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, hdl) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_start_namespace_decl_handler, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, hdl) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_end_namespace_decl_handler, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, hdl) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parse, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, data) - ZEND_ARG_INFO(0, isfinal) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parse_into_struct, 0, 0, 3) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, data) - ZEND_ARG_INFO(1, values) - ZEND_ARG_INFO(1, index) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_error_code, 0, 0, 1) - ZEND_ARG_INFO(0, parser) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_error_string, 0, 0, 1) - ZEND_ARG_INFO(0, code) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_current_line_number, 0, 0, 1) - ZEND_ARG_INFO(0, parser) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_current_column_number, 0, 0, 1) - ZEND_ARG_INFO(0, parser) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_current_byte_index, 0, 0, 1) - ZEND_ARG_INFO(0, parser) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_free, 0, 0, 1) - ZEND_ARG_INFO(0, parser) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_set_option, 0, 0, 3) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, option) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_get_option, 0, 0, 2) - ZEND_ARG_INFO(0, parser) - ZEND_ARG_INFO(0, option) -ZEND_END_ARG_INFO() - -static const zend_function_entry xml_functions[] = { - PHP_FE(xml_parser_create, arginfo_xml_parser_create) - PHP_FE(xml_parser_create_ns, arginfo_xml_parser_create_ns) - PHP_FE(xml_set_object, arginfo_xml_set_object) - PHP_FE(xml_set_element_handler, arginfo_xml_set_element_handler) - PHP_FE(xml_set_character_data_handler, arginfo_xml_set_character_data_handler) - PHP_FE(xml_set_processing_instruction_handler, arginfo_xml_set_processing_instruction_handler) - PHP_FE(xml_set_default_handler, arginfo_xml_set_default_handler) - PHP_FE(xml_set_unparsed_entity_decl_handler,arginfo_xml_set_unparsed_entity_decl_handler) - PHP_FE(xml_set_notation_decl_handler, arginfo_xml_set_notation_decl_handler) - PHP_FE(xml_set_external_entity_ref_handler, arginfo_xml_set_external_entity_ref_handler) - PHP_FE(xml_set_start_namespace_decl_handler,arginfo_xml_set_start_namespace_decl_handler) - PHP_FE(xml_set_end_namespace_decl_handler, arginfo_xml_set_end_namespace_decl_handler) - PHP_FE(xml_parse, arginfo_xml_parse) - PHP_FE(xml_parse_into_struct, arginfo_xml_parse_into_struct) - PHP_FE(xml_get_error_code, arginfo_xml_get_error_code) - PHP_FE(xml_error_string, arginfo_xml_error_string) - PHP_FE(xml_get_current_line_number, arginfo_xml_get_current_line_number) - PHP_FE(xml_get_current_column_number, arginfo_xml_get_current_column_number) - PHP_FE(xml_get_current_byte_index, arginfo_xml_get_current_byte_index) - PHP_FE(xml_parser_free, arginfo_xml_parser_free) - PHP_FE(xml_parser_set_option, arginfo_xml_parser_set_option) - PHP_FE(xml_parser_get_option, arginfo_xml_parser_get_option) - PHP_FE_END -}; - #ifdef LIBXML_EXPAT_COMPAT static const zend_module_dep xml_deps[] = { ZEND_MOD_REQUIRED("libxml") @@ -340,7 +197,7 @@ zend_module_entry xml_module_entry = { STANDARD_MODULE_HEADER, #endif "xml", /* extension name */ - xml_functions, /* extension function list */ + ext_functions, /* extension function list */ PHP_MINIT(xml), /* extension-wide startup function */ NULL, /* extension-wide shutdown function */ NULL, /* per-request startup function */ @@ -366,9 +223,6 @@ const xml_encoding xml_encodings[] = { static XML_Memory_Handling_Suite php_xml_mem_hdlrs; -/* True globals, no need for thread safety */ -static int le_xml_parser; - /* }}} */ /* {{{ startup, shutdown and info functions */ @@ -399,7 +253,20 @@ static void php_xml_free_wrapper(void *ptr) PHP_MINIT_FUNCTION(xml) { - le_xml_parser = zend_register_list_destructors_ex(xml_parser_dtor, NULL, "xml", module_number); + zend_class_entry ce; + INIT_CLASS_ENTRY(ce, "XMLParser", class_XMLParser_methods); + xml_parser_ce = zend_register_internal_class(&ce); + xml_parser_ce->create_object = xml_parser_create_object; + xml_parser_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; + xml_parser_ce->serialize = zend_class_serialize_deny; + xml_parser_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&xml_parser_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + xml_parser_object_handlers.offset = XtOffsetOf(xml_parser, std); + xml_parser_object_handlers.free_obj = xml_parser_free_obj; + xml_parser_object_handlers.get_gc = xml_parser_get_gc; + xml_parser_object_handlers.get_constructor = xml_parser_get_constructor; + xml_parser_object_handlers.clone_obj = NULL; REGISTER_LONG_CONSTANT("XML_ERROR_NONE", XML_ERROR_NONE, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("XML_ERROR_NO_MEMORY", XML_ERROR_NO_MEMORY, CONST_CS|CONST_PERSISTENT); @@ -474,10 +341,26 @@ static void _xml_xmlchar_zval(const XML_Char *s, int len, const XML_Char *encodi } /* }}} */ -/* {{{ xml_parser_dtor() */ -static void xml_parser_dtor(zend_resource *rsrc) +static inline xml_parser *xml_parser_from_obj(zend_object *obj) { + return (xml_parser *)((char *)(obj) - XtOffsetOf(xml_parser, std)); +} + +#define Z_XMLPARSER_P(zv) xml_parser_from_obj(Z_OBJ_P(zv)) + +static zend_object *xml_parser_create_object(zend_class_entry *class_type) { + xml_parser *intern = zend_object_alloc(sizeof(xml_parser), class_type); + memset(intern, 0, sizeof(xml_parser) - sizeof(zend_object)); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &xml_parser_object_handlers; + + return &intern->std; +} + +static void xml_parser_free_obj(zend_object *object) { - xml_parser *parser = (xml_parser *)rsrc->ptr; + xml_parser *parser = xml_parser_from_obj(object); if (parser->parser) { XML_ParserFree(parser->parser); @@ -528,9 +411,21 @@ static void xml_parser_dtor(zend_resource *rsrc) zval_ptr_dtor(&parser->object); } - efree(parser); + zend_object_std_dtor(&parser->std); +} + +static HashTable *xml_parser_get_gc(zend_object *object, zval **table, int *n) +{ + xml_parser *parser = xml_parser_from_obj(object); + *table = &parser->object; + *n = XML_PARSER_NUM_ZVALS; + return zend_std_get_properties(object); +} + +static zend_function *xml_parser_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct XMLParser, use xml_parser_create() or xml_parser_create_ns() instead"); + return NULL; } -/* }}} */ /* {{{ xml_set_handler() */ static void xml_set_handler(zval *handler, zval *data) @@ -569,8 +464,7 @@ static void xml_call_handler(xml_parser *parser, zval *handler, zend_function *f fci.retval = retval; fci.param_count = argc; fci.params = argv; - fci.no_separation = 0; - /*fci.function_handler_cache = &function_ptr;*/ + fci.named_params = NULL; result = zend_call_function(&fci, NULL); if (result == FAILURE) { @@ -1117,8 +1011,8 @@ static void php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAMETERS, int ns_supp XML_Char *encoding; - if (zend_parse_parameters(ZEND_NUM_ARGS(), (ns_support ? "|ss": "|s"), &encoding_param, &encoding_param_len, &ns_param, &ns_param_len) == FAILURE) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), (ns_support ? "|s!s": "|s!"), &encoding_param, &encoding_param_len, &ns_param, &ns_param_len) == FAILURE) { + RETURN_THROWS(); } if (encoding_param != NULL) { @@ -1135,8 +1029,8 @@ static void php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAMETERS, int ns_supp } else if (strcasecmp(encoding_param, "US-ASCII") == 0) { encoding = (XML_Char*)"US-ASCII"; } else { - php_error_docref(NULL, E_WARNING, "unsupported source encoding \"%s\"", encoding_param); - RETURN_FALSE; + zend_argument_value_error(1, "is not a supported source encoding"); + RETURN_THROWS(); } } else { encoding = XML(default_encoding); @@ -1146,7 +1040,8 @@ static void php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAMETERS, int ns_supp ns_param = ":"; } - parser = ecalloc(1, sizeof(xml_parser)); + object_init_ex(return_value, xml_parser_ce); + parser = Z_XMLPARSER_P(return_value); parser->parser = XML_ParserCreate_MM((auto_detect ? NULL : encoding), &php_xml_mem_hdlrs, (XML_Char*)ns_param); @@ -1155,73 +1050,54 @@ static void php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAMETERS, int ns_supp parser->isparsing = 0; XML_SetUserData(parser->parser, parser); - - RETVAL_RES(zend_register_resource(parser, le_xml_parser)); ZVAL_COPY_VALUE(&parser->index, return_value); } /* }}} */ -/* {{{ proto resource xml_parser_create([string encoding]) - Create an XML parser */ +/* {{{ Create an XML parser */ PHP_FUNCTION(xml_parser_create) { php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } /* }}} */ -/* {{{ proto resource xml_parser_create_ns([string encoding [, string sep]]) - Create an XML parser */ +/* {{{ Create an XML parser */ PHP_FUNCTION(xml_parser_create_ns) { php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); } /* }}} */ -/* {{{ proto int xml_set_object(resource parser, object &obj) - Set up object which should be used for callbacks */ +/* {{{ Set up object which should be used for callbacks */ PHP_FUNCTION(xml_set_object) { xml_parser *parser; zval *pind, *mythis; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ro", &pind, &mythis) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oo", &pind, xml_parser_ce, &mythis) == FAILURE) { + RETURN_THROWS(); } - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; - } + parser = Z_XMLPARSER_P(pind); - /* please leave this commented - or ask thies@thieso.net before doing it (again) */ - if (!Z_ISUNDEF(parser->object)) { - zval_ptr_dtor(&parser->object); - } - - /* please leave this commented - or ask thies@thieso.net before doing it (again) */ - /* zval_add_ref(&parser->object); */ - - Z_ADDREF_P(mythis); - ZVAL_OBJ(&parser->object, Z_OBJ_P(mythis)); + zval_ptr_dtor(&parser->object); + ZVAL_OBJ_COPY(&parser->object, Z_OBJ_P(mythis)); RETVAL_TRUE; } /* }}} */ -/* {{{ proto int xml_set_element_handler(resource parser, string shdl, string ehdl) - Set up start and end element handlers */ +/* {{{ Set up start and end element handlers */ PHP_FUNCTION(xml_set_element_handler) { xml_parser *parser; zval *pind, *shdl, *ehdl; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rzz", &pind, &shdl, &ehdl) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ozz", &pind, xml_parser_ce, &shdl, &ehdl) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); xml_set_handler(&parser->startElementHandler, shdl); xml_set_handler(&parser->endElementHandler, ehdl); XML_SetElementHandler(parser->parser, _xml_startElementHandler, _xml_endElementHandler); @@ -1229,176 +1105,143 @@ PHP_FUNCTION(xml_set_element_handler) } /* }}} */ -/* {{{ proto int xml_set_character_data_handler(resource parser, string hdl) - Set up character data handler */ +/* {{{ Set up character data handler */ PHP_FUNCTION(xml_set_character_data_handler) { xml_parser *parser; zval *pind, *hdl; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz", &pind, xml_parser_ce, &hdl) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); xml_set_handler(&parser->characterDataHandler, hdl); XML_SetCharacterDataHandler(parser->parser, _xml_characterDataHandler); RETVAL_TRUE; } /* }}} */ -/* {{{ proto int xml_set_processing_instruction_handler(resource parser, string hdl) - Set up processing instruction (PI) handler */ +/* {{{ Set up processing instruction (PI) handler */ PHP_FUNCTION(xml_set_processing_instruction_handler) { xml_parser *parser; zval *pind, *hdl; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz", &pind, xml_parser_ce, &hdl) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); xml_set_handler(&parser->processingInstructionHandler, hdl); XML_SetProcessingInstructionHandler(parser->parser, _xml_processingInstructionHandler); RETVAL_TRUE; } /* }}} */ -/* {{{ proto int xml_set_default_handler(resource parser, string hdl) - Set up default handler */ +/* {{{ Set up default handler */ PHP_FUNCTION(xml_set_default_handler) { xml_parser *parser; zval *pind, *hdl; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz", &pind, xml_parser_ce, &hdl) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); xml_set_handler(&parser->defaultHandler, hdl); XML_SetDefaultHandler(parser->parser, _xml_defaultHandler); RETVAL_TRUE; } /* }}} */ -/* {{{ proto int xml_set_unparsed_entity_decl_handler(resource parser, string hdl) - Set up unparsed entity declaration handler */ +/* {{{ Set up unparsed entity declaration handler */ PHP_FUNCTION(xml_set_unparsed_entity_decl_handler) { xml_parser *parser; zval *pind, *hdl; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz", &pind, xml_parser_ce, &hdl) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); xml_set_handler(&parser->unparsedEntityDeclHandler, hdl); XML_SetUnparsedEntityDeclHandler(parser->parser, _xml_unparsedEntityDeclHandler); RETVAL_TRUE; } /* }}} */ -/* {{{ proto int xml_set_notation_decl_handler(resource parser, string hdl) - Set up notation declaration handler */ +/* {{{ Set up notation declaration handler */ PHP_FUNCTION(xml_set_notation_decl_handler) { xml_parser *parser; zval *pind, *hdl; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz", &pind, xml_parser_ce, &hdl) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); xml_set_handler(&parser->notationDeclHandler, hdl); XML_SetNotationDeclHandler(parser->parser, _xml_notationDeclHandler); RETVAL_TRUE; } /* }}} */ -/* {{{ proto int xml_set_external_entity_ref_handler(resource parser, string hdl) - Set up external entity reference handler */ +/* {{{ Set up external entity reference handler */ PHP_FUNCTION(xml_set_external_entity_ref_handler) { xml_parser *parser; zval *pind, *hdl; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz", &pind, xml_parser_ce, &hdl) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); xml_set_handler(&parser->externalEntityRefHandler, hdl); XML_SetExternalEntityRefHandler(parser->parser, (void *) _xml_externalEntityRefHandler); RETVAL_TRUE; } /* }}} */ -/* {{{ proto int xml_set_start_namespace_decl_handler(resource parser, string hdl) - Set up character data handler */ +/* {{{ Set up character data handler */ PHP_FUNCTION(xml_set_start_namespace_decl_handler) { xml_parser *parser; zval *pind, *hdl; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz", &pind, xml_parser_ce, &hdl) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); xml_set_handler(&parser->startNamespaceDeclHandler, hdl); XML_SetStartNamespaceDeclHandler(parser->parser, _xml_startNamespaceDeclHandler); RETVAL_TRUE; } /* }}} */ -/* {{{ proto int xml_set_end_namespace_decl_handler(resource parser, string hdl) - Set up character data handler */ +/* {{{ Set up character data handler */ PHP_FUNCTION(xml_set_end_namespace_decl_handler) { xml_parser *parser; zval *pind, *hdl; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz", &pind, xml_parser_ce, &hdl) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); xml_set_handler(&parser->endNamespaceDeclHandler, hdl); XML_SetEndNamespaceDeclHandler(parser->parser, _xml_endNamespaceDeclHandler); RETVAL_TRUE; } /* }}} */ -/* {{{ proto int xml_parse(resource parser, string data [, bool isFinal]) - Start parsing an XML document */ +/* {{{ Start parsing an XML document */ PHP_FUNCTION(xml_parse) { xml_parser *parser; @@ -1408,14 +1251,11 @@ PHP_FUNCTION(xml_parse) int ret; zend_bool isFinal = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|b", &pind, &data, &data_len, &isFinal) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|b", &pind, xml_parser_ce, &data, &data_len, &isFinal) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); parser->isparsing = 1; ret = XML_Parse(parser->parser, (XML_Char*)data, data_len, isFinal); parser->isparsing = 0; @@ -1424,9 +1264,7 @@ PHP_FUNCTION(xml_parse) /* }}} */ -/* {{{ proto int xml_parse_into_struct(resource parser, string data, array &values [, array &index ]) - Parsing a XML document */ - +/* {{{ Parsing a XML document */ PHP_FUNCTION(xml_parse_into_struct) { xml_parser *parser; @@ -1435,24 +1273,22 @@ PHP_FUNCTION(xml_parse_into_struct) size_t data_len; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsz|z", &pind, &data, &data_len, &xdata, &info) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osz|z", &pind, xml_parser_ce, &data, &data_len, &xdata, &info) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); + if (info) { info = zend_try_array_init(info); if (!info) { - return; + RETURN_THROWS(); } } - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; - } - xdata = zend_try_array_init(xdata); if (!xdata) { - return; + RETURN_THROWS(); } ZVAL_COPY_VALUE(&parser->data, xdata); @@ -1475,34 +1311,29 @@ PHP_FUNCTION(xml_parse_into_struct) } /* }}} */ -/* {{{ proto int xml_get_error_code(resource parser) - Get XML parser error code */ +/* {{{ Get XML parser error code */ PHP_FUNCTION(xml_get_error_code) { xml_parser *parser; zval *pind; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pind, xml_parser_ce) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); RETURN_LONG((zend_long)XML_GetErrorCode(parser->parser)); } /* }}} */ -/* {{{ proto string xml_error_string(int code) - Get XML parser error string */ +/* {{{ Get XML parser error string */ PHP_FUNCTION(xml_error_string) { zend_long code; char *str; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &code) == FAILURE) { - return; + RETURN_THROWS(); } str = (char *)XML_ErrorString((int)code); @@ -1512,107 +1343,83 @@ PHP_FUNCTION(xml_error_string) } /* }}} */ -/* {{{ proto int xml_get_current_line_number(resource parser) - Get current line number for an XML parser */ +/* {{{ Get current line number for an XML parser */ PHP_FUNCTION(xml_get_current_line_number) { xml_parser *parser; zval *pind; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pind, xml_parser_ce) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); RETVAL_LONG(XML_GetCurrentLineNumber(parser->parser)); } /* }}} */ -/* {{{ proto int xml_get_current_column_number(resource parser) - Get current column number for an XML parser */ +/* {{{ Get current column number for an XML parser */ PHP_FUNCTION(xml_get_current_column_number) { xml_parser *parser; zval *pind; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pind, xml_parser_ce) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); RETVAL_LONG(XML_GetCurrentColumnNumber(parser->parser)); } /* }}} */ -/* {{{ proto int xml_get_current_byte_index(resource parser) - Get current byte index for an XML parser */ +/* {{{ Get current byte index for an XML parser */ PHP_FUNCTION(xml_get_current_byte_index) { xml_parser *parser; zval *pind; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pind, xml_parser_ce) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); RETVAL_LONG(XML_GetCurrentByteIndex(parser->parser)); } /* }}} */ -/* {{{ proto int xml_parser_free(resource parser) - Free an XML parser */ +/* {{{ Free an XML parser */ PHP_FUNCTION(xml_parser_free) { zval *pind; xml_parser *parser; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pind, xml_parser_ce) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); if (parser->isparsing == 1) { php_error_docref(NULL, E_WARNING, "Parser cannot be freed while it is parsing."); RETURN_FALSE; } - if (zend_list_close(Z_RES(parser->index)) == FAILURE) { - RETURN_FALSE; - } - RETURN_TRUE; } /* }}} */ -/* {{{ proto int xml_parser_set_option(resource parser, int option, mixed value) - Set options in an XML parser */ +/* {{{ Set options in an XML parser */ PHP_FUNCTION(xml_parser_set_option) { xml_parser *parser; zval *pind, *val; zend_long opt; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlz", &pind, &opt, &val) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olz", &pind, xml_parser_ce, &opt, &val) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); switch (opt) { case PHP_XML_OPTION_CASE_FOLDING: parser->case_folding = zval_get_long(val); @@ -1620,7 +1427,7 @@ PHP_FUNCTION(xml_parser_set_option) case PHP_XML_OPTION_SKIP_TAGSTART: parser->toffset = zval_get_long(val); if (parser->toffset < 0) { - php_error_docref(NULL, E_NOTICE, "tagstart ignored, because it is out of range"); + php_error_docref(NULL, E_WARNING, "tagstart ignored, because it is out of range"); parser->toffset = 0; } break; @@ -1630,42 +1437,39 @@ PHP_FUNCTION(xml_parser_set_option) case PHP_XML_OPTION_TARGET_ENCODING: { const xml_encoding *enc; if (!try_convert_to_string(val)) { - return; + RETURN_THROWS(); } enc = xml_get_encoding((XML_Char*)Z_STRVAL_P(val)); if (enc == NULL) { - php_error_docref(NULL, E_WARNING, "Unsupported target encoding \"%s\"", Z_STRVAL_P(val)); - RETURN_FALSE; + zend_argument_value_error(3, "is not a supported target encoding"); + RETURN_THROWS(); } + parser->target_encoding = enc->name; break; } default: - php_error_docref(NULL, E_WARNING, "Unknown option"); - RETURN_FALSE; + zend_argument_value_error(2, "must be a PHP_XML_OPTION_* constant"); + RETURN_THROWS(); break; } RETVAL_TRUE; } /* }}} */ -/* {{{ proto int xml_parser_get_option(resource parser, int option) - Get options from an XML parser */ +/* {{{ Get options from an XML parser */ PHP_FUNCTION(xml_parser_get_option) { xml_parser *parser; zval *pind; zend_long opt; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &pind, &opt) == FAILURE) { - return; - } - - if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pind, xml_parser_ce, &opt) == FAILURE) { + RETURN_THROWS(); } + parser = Z_XMLPARSER_P(pind); switch (opt) { case PHP_XML_OPTION_CASE_FOLDING: RETURN_LONG(parser->case_folding); @@ -1680,12 +1484,9 @@ PHP_FUNCTION(xml_parser_get_option) RETURN_STRING((char *)parser->target_encoding); break; default: - php_error_docref(NULL, E_WARNING, "Unknown option"); - RETURN_FALSE; - break; + zend_argument_value_error(2, "must be a PHP_XML_OPTION_* constant"); + RETURN_THROWS(); } - - RETVAL_FALSE; /* never reached */ } /* }}} */ diff --git a/ext/xml/xml.stub.php b/ext/xml/xml.stub.php new file mode 100644 index 0000000000..6dc10d58b5 --- /dev/null +++ b/ext/xml/xml.stub.php @@ -0,0 +1,68 @@ +<?php + +/** @generate-function-entries */ + +function xml_parser_create(?string $encoding = null): XMLParser {} + +function xml_parser_create_ns(?string $encoding = null, string $separator = ":"): XMLParser {} + +function xml_set_object(XMLParser $parser, object $object): bool {} + +/** + * @param callable $start_handler + * @param callable $end_handler + */ +function xml_set_element_handler(XMLParser $parser, $start_handler, $end_handler): bool {} + +/** @param callable $handler */ +function xml_set_character_data_handler(XMLParser $parser, $handler): bool {} + +/** @param callable $handler */ +function xml_set_processing_instruction_handler(XMLParser $parser, $handler): bool {} + +/** @param callable $handler */ +function xml_set_default_handler(XMLParser $parser, $handler): bool {} + +/** @param callable $handler */ +function xml_set_unparsed_entity_decl_handler(XMLParser $parser, $handler): bool {} + +/** @param callable $handler */ +function xml_set_notation_decl_handler(XMLParser $parser, $handler): bool {} + +/** @param callable $handler */ +function xml_set_external_entity_ref_handler(XMLParser $parser, $handler): bool {} + +/** @param callable $handler */ +function xml_set_start_namespace_decl_handler(XMLParser $parser, $handler): bool {} + +/** @param callable $handler */ +function xml_set_end_namespace_decl_handler(XMLParser $parser, $handler): bool {} + +function xml_parse(XMLParser $parser, string $data, bool $is_final = false): int {} + +/** + * @param array $values + * @param array $index + */ +function xml_parse_into_struct(XMLParser $parser, string $data, &$values, &$index = null): int {} + +function xml_get_error_code(XMLParser $parser): int {} + +function xml_error_string(int $error_code): ?string {} + +function xml_get_current_line_number(XMLParser $parser): int {} + +function xml_get_current_column_number(XMLParser $parser): int {} + +function xml_get_current_byte_index(XMLParser $parser): int {} + +function xml_parser_free(XMLParser $parser): bool {} + +/** @param string|int $value */ +function xml_parser_set_option(XMLParser $parser, int $option, $value): bool {} + +function xml_parser_get_option(XMLParser $parser, int $option): string|int {} + +final class XMLParser +{ +} diff --git a/ext/xml/xml_arginfo.h b/ext/xml/xml_arginfo.h new file mode 100644 index 0000000000..26187dad3d --- /dev/null +++ b/ext/xml/xml_arginfo.h @@ -0,0 +1,139 @@ +/* This is a generated file, edit the .stub.php file instead. + * Stub hash: d42215062c41775bae538cd310bc60e63fa06a8e */ + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_xml_parser_create, 0, 0, XMLParser, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_xml_parser_create_ns, 0, 0, XMLParser, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, separator, IS_STRING, 0, "\":\"") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_set_object, 0, 2, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, parser, XMLParser, 0) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_set_element_handler, 0, 3, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, parser, XMLParser, 0) + ZEND_ARG_INFO(0, start_handler) + ZEND_ARG_INFO(0, end_handler) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_set_character_data_handler, 0, 2, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, parser, XMLParser, 0) + ZEND_ARG_INFO(0, handler) +ZEND_END_ARG_INFO() + +#define arginfo_xml_set_processing_instruction_handler arginfo_xml_set_character_data_handler + +#define arginfo_xml_set_default_handler arginfo_xml_set_character_data_handler + +#define arginfo_xml_set_unparsed_entity_decl_handler arginfo_xml_set_character_data_handler + +#define arginfo_xml_set_notation_decl_handler arginfo_xml_set_character_data_handler + +#define arginfo_xml_set_external_entity_ref_handler arginfo_xml_set_character_data_handler + +#define arginfo_xml_set_start_namespace_decl_handler arginfo_xml_set_character_data_handler + +#define arginfo_xml_set_end_namespace_decl_handler arginfo_xml_set_character_data_handler + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_parse, 0, 2, IS_LONG, 0) + ZEND_ARG_OBJ_INFO(0, parser, XMLParser, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, is_final, _IS_BOOL, 0, "false") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_parse_into_struct, 0, 3, IS_LONG, 0) + ZEND_ARG_OBJ_INFO(0, parser, XMLParser, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_INFO(1, values) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, index, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_get_error_code, 0, 1, IS_LONG, 0) + ZEND_ARG_OBJ_INFO(0, parser, XMLParser, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_error_string, 0, 1, IS_STRING, 1) + ZEND_ARG_TYPE_INFO(0, error_code, IS_LONG, 0) +ZEND_END_ARG_INFO() + +#define arginfo_xml_get_current_line_number arginfo_xml_get_error_code + +#define arginfo_xml_get_current_column_number arginfo_xml_get_error_code + +#define arginfo_xml_get_current_byte_index arginfo_xml_get_error_code + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_parser_free, 0, 1, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, parser, XMLParser, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_parser_set_option, 0, 3, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, parser, XMLParser, 0) + ZEND_ARG_TYPE_INFO(0, option, IS_LONG, 0) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_xml_parser_get_option, 0, 2, MAY_BE_STRING|MAY_BE_LONG) + ZEND_ARG_OBJ_INFO(0, parser, XMLParser, 0) + ZEND_ARG_TYPE_INFO(0, option, IS_LONG, 0) +ZEND_END_ARG_INFO() + + +ZEND_FUNCTION(xml_parser_create); +ZEND_FUNCTION(xml_parser_create_ns); +ZEND_FUNCTION(xml_set_object); +ZEND_FUNCTION(xml_set_element_handler); +ZEND_FUNCTION(xml_set_character_data_handler); +ZEND_FUNCTION(xml_set_processing_instruction_handler); +ZEND_FUNCTION(xml_set_default_handler); +ZEND_FUNCTION(xml_set_unparsed_entity_decl_handler); +ZEND_FUNCTION(xml_set_notation_decl_handler); +ZEND_FUNCTION(xml_set_external_entity_ref_handler); +ZEND_FUNCTION(xml_set_start_namespace_decl_handler); +ZEND_FUNCTION(xml_set_end_namespace_decl_handler); +ZEND_FUNCTION(xml_parse); +ZEND_FUNCTION(xml_parse_into_struct); +ZEND_FUNCTION(xml_get_error_code); +ZEND_FUNCTION(xml_error_string); +ZEND_FUNCTION(xml_get_current_line_number); +ZEND_FUNCTION(xml_get_current_column_number); +ZEND_FUNCTION(xml_get_current_byte_index); +ZEND_FUNCTION(xml_parser_free); +ZEND_FUNCTION(xml_parser_set_option); +ZEND_FUNCTION(xml_parser_get_option); + + +static const zend_function_entry ext_functions[] = { + ZEND_FE(xml_parser_create, arginfo_xml_parser_create) + ZEND_FE(xml_parser_create_ns, arginfo_xml_parser_create_ns) + ZEND_FE(xml_set_object, arginfo_xml_set_object) + ZEND_FE(xml_set_element_handler, arginfo_xml_set_element_handler) + ZEND_FE(xml_set_character_data_handler, arginfo_xml_set_character_data_handler) + ZEND_FE(xml_set_processing_instruction_handler, arginfo_xml_set_processing_instruction_handler) + ZEND_FE(xml_set_default_handler, arginfo_xml_set_default_handler) + ZEND_FE(xml_set_unparsed_entity_decl_handler, arginfo_xml_set_unparsed_entity_decl_handler) + ZEND_FE(xml_set_notation_decl_handler, arginfo_xml_set_notation_decl_handler) + ZEND_FE(xml_set_external_entity_ref_handler, arginfo_xml_set_external_entity_ref_handler) + ZEND_FE(xml_set_start_namespace_decl_handler, arginfo_xml_set_start_namespace_decl_handler) + ZEND_FE(xml_set_end_namespace_decl_handler, arginfo_xml_set_end_namespace_decl_handler) + ZEND_FE(xml_parse, arginfo_xml_parse) + ZEND_FE(xml_parse_into_struct, arginfo_xml_parse_into_struct) + ZEND_FE(xml_get_error_code, arginfo_xml_get_error_code) + ZEND_FE(xml_error_string, arginfo_xml_error_string) + ZEND_FE(xml_get_current_line_number, arginfo_xml_get_current_line_number) + ZEND_FE(xml_get_current_column_number, arginfo_xml_get_current_column_number) + ZEND_FE(xml_get_current_byte_index, arginfo_xml_get_current_byte_index) + ZEND_FE(xml_parser_free, arginfo_xml_parser_free) + ZEND_FE(xml_parser_set_option, arginfo_xml_parser_set_option) + ZEND_FE(xml_parser_get_option, arginfo_xml_parser_get_option) + ZEND_FE_END +}; + + +static const zend_function_entry class_XMLParser_methods[] = { + ZEND_FE_END +}; |
