-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ext/xml: Refactor extension to use FCC instead of zvals for handlers #12340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
e1f967f
[skip ci] [W.I.P.] ext/xml: Refactor extension to use FCC instead of …
Girgias 5e7baeb
Fix memory leak of parser->object
nielsdos c8c5ac2
Clear initialized status after deleting handler
nielsdos 457c9ac
It's not really a libxml function, can also be expat
nielsdos 4dd9a73
fixup
nielsdos 9c710c2
Fix typo?
nielsdos 71e2e3e
Fix start element handler not getting called
nielsdos 6b29565
Add todo
nielsdos 8f4660c
Fix leak
nielsdos 465574b
Add trampoline test for generic XMLParser handler
Girgias b2f5a74
Deal with error cases
Girgias 4f3520c
TODO Comment
Girgias e3d834d
Stop special casing false value type
Girgias 13325eb
Use proper param types in gen_stub
Girgias f61c609
REVIEW
Girgias 7a4175b
Trampo test + fix bug
Girgias 41e31d6
Change parser.object to be a zend_object*
Girgias 69e5b75
[skip ci] Check old FCCs for new set object
Girgias ce61a80
[skip ci] add ref
Girgias a5dab5d
UPGRADING
Girgias 04eae36
Fix behaviour that proper callables could change
Girgias 7a68757
Improve error when swapping object
Girgias edc99d5
Use new F ZPP type check
Girgias ad61613
Remove things related to unknown encoding handler
nielsdos 654b381
Fix memleak
nielsdos 4ae94e5
Nits
Girgias File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,18 +6,20 @@ xml | |
edgarsandi - <[email protected]> | ||
--FILE-- | ||
<?php | ||
function start_elem($parser, $xml) { | ||
xml_parse($parser, $xml); | ||
} | ||
function start_elem($parser, $xml) { | ||
xml_parse($parser, $xml); | ||
} | ||
|
||
function dummy() {} | ||
|
||
$xml = <<<HERE | ||
<a xmlns="ahihi"> | ||
<bar foo="ahihi"/> | ||
</a> | ||
$xml = <<<HERE | ||
<a xmlns="ahihi"> | ||
<bar foo="ahihi"/> | ||
</a> | ||
HERE; | ||
|
||
$parser = xml_parser_create_ns(); | ||
xml_set_element_handler($parser, 'start_elem', 'ahihi'); | ||
xml_set_element_handler($parser, 'start_elem', 'dummy'); | ||
xml_parse($parser, $xml); | ||
?> | ||
--EXPECTF-- | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
--TEST-- | ||
Test xml_set_element_handler handlers as trampoline callback | ||
--EXTENSIONS-- | ||
xml | ||
--FILE-- | ||
<?php | ||
|
||
class CustomXmlParser | ||
{ | ||
public function startHandler($XmlParser, $tag, $attr) | ||
{ | ||
echo 'Method start handler: ', $tag, PHP_EOL; | ||
} | ||
|
||
public function endHandler($XmlParser, $tag) | ||
{ | ||
echo 'Method end handler: ', $tag, PHP_EOL; | ||
} | ||
} | ||
|
||
$customParser = new CustomXmlParser; | ||
|
||
class TrampolineTest { | ||
public function __call(string $name, array $arguments) { | ||
echo 'Trampoline for ', $name, PHP_EOL; | ||
echo 'Tag: ', $arguments[1], PHP_EOL; | ||
} | ||
} | ||
|
||
$o = new TrampolineTest(); | ||
$startCallback = [$o, 'start_handler']; | ||
$endCallback = [$o, 'end_handler']; | ||
|
||
$xml = <<<HERE | ||
<a> | ||
<b/> | ||
<c>Text</c> | ||
</a> | ||
HERE; | ||
|
||
echo "Both handlers are trampolines:\n"; | ||
$parser = xml_parser_create(); | ||
xml_set_element_handler($parser, $startCallback, $endCallback); | ||
xml_parse($parser, $xml, true); | ||
xml_parser_free($parser); | ||
|
||
echo "\nStart handler is trampoline, end handler method string:\n"; | ||
$parser = xml_parser_create(); | ||
xml_set_object($parser, $customParser); | ||
xml_set_element_handler($parser, $startCallback, 'endHandler'); | ||
xml_parse($parser, $xml, true); | ||
xml_parser_free($parser); | ||
|
||
echo "\nEnd handler is trampoline, start handler method string:\n"; | ||
$parser = xml_parser_create(); | ||
xml_set_object($parser, $customParser); | ||
xml_set_element_handler($parser, 'startHandler', $endCallback); | ||
xml_parse($parser, $xml, true); | ||
xml_parser_free($parser); | ||
|
||
?> | ||
--EXPECT-- | ||
Both handlers are trampolines: | ||
Trampoline for start_handler | ||
Tag: A | ||
Trampoline for start_handler | ||
Tag: B | ||
Trampoline for end_handler | ||
Tag: B | ||
Trampoline for start_handler | ||
Tag: C | ||
Trampoline for end_handler | ||
Tag: C | ||
Trampoline for end_handler | ||
Tag: A | ||
|
||
Start handler is trampoline, end handler method string: | ||
Trampoline for start_handler | ||
Tag: A | ||
Trampoline for start_handler | ||
Tag: B | ||
Method end handler: B | ||
Trampoline for start_handler | ||
Tag: C | ||
Method end handler: C | ||
Method end handler: A | ||
|
||
End handler is trampoline, start handler method string: | ||
Method start handler: A | ||
Method start handler: B | ||
Trampoline for end_handler | ||
Tag: B | ||
Method start handler: C | ||
Trampoline for end_handler | ||
Tag: C | ||
Trampoline for end_handler | ||
Tag: A |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
--TEST-- | ||
Test xml_set_element_handler handlers as trampoline callback | ||
--EXTENSIONS-- | ||
xml | ||
--FILE-- | ||
<?php | ||
|
||
class TrampolineTest { | ||
public function __call(string $name, array $arguments) { | ||
echo 'Trampoline for ', $name, PHP_EOL; | ||
echo 'Tag: ', $arguments[1], PHP_EOL; | ||
} | ||
} | ||
|
||
$o = new TrampolineTest(); | ||
$startCallback = [$o, 'start_handler']; | ||
$endCallback = [$o, 'end_handler']; | ||
|
||
$xml = <<<HERE | ||
<a> | ||
<b/> | ||
<c>Text</c> | ||
</a> | ||
HERE; | ||
|
||
$parser = xml_parser_create(); | ||
echo "2nd arg is rubbish:\n"; | ||
try { | ||
xml_set_element_handler($parser, [], $endCallback); | ||
} catch (\Throwable $e) { | ||
echo $e::class, ': ', $e->getMessage(), PHP_EOL; | ||
} | ||
echo "3rd arg is rubbish:\n"; | ||
try { | ||
xml_set_element_handler($parser, $startCallback, []); | ||
} catch (\Throwable $e) { | ||
echo $e::class, ': ', $e->getMessage(), PHP_EOL; | ||
} | ||
xml_parser_free($parser); | ||
|
||
?> | ||
--EXPECT-- | ||
2nd arg is rubbish: | ||
TypeError: xml_set_element_handler(): Argument #2 ($start_handler) must be of type callable|string|null | ||
3rd arg is rubbish: | ||
TypeError: xml_set_element_handler(): Argument #2 ($start_handler) must be of type callable|string|null |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--TEST-- | ||
Error conditions when setting invalid handler callables | ||
--EXTENSIONS-- | ||
xml | ||
--FILE-- | ||
<?php | ||
declare(strict_types=1); | ||
|
||
/* Use xml_set_processing_instruction_handler() for generic implementation */ | ||
echo 'Invalid $parser:', PHP_EOL; | ||
$obj = new stdClass(); | ||
try { | ||
xml_set_processing_instruction_handler($obj, null); | ||
} catch (\Throwable $e) { | ||
echo $e::class, ': ', $e->getMessage(), PHP_EOL; | ||
} | ||
|
||
/* Create valid parser */ | ||
$parser = xml_parser_create(); | ||
|
||
echo 'Invalid callable type true:', PHP_EOL; | ||
try { | ||
xml_set_processing_instruction_handler($parser, true); | ||
} catch (\Throwable $e) { | ||
echo $e::class, ': ', $e->getMessage(), PHP_EOL; | ||
} | ||
|
||
echo 'Invalid callable type int:', PHP_EOL; | ||
try { | ||
xml_set_processing_instruction_handler($parser, 10); | ||
} catch (\Throwable $e) { | ||
echo $e::class, ': ', $e->getMessage(), PHP_EOL; | ||
} | ||
|
||
echo 'String not callable and no object set:', PHP_EOL; | ||
try { | ||
xml_set_processing_instruction_handler($parser, "nonexistent_method"); | ||
} catch (\Throwable $e) { | ||
echo $e::class, ': ', $e->getMessage(), PHP_EOL; | ||
} | ||
|
||
echo 'String non existent method on set object:', PHP_EOL; | ||
xml_set_object($parser, $obj); | ||
try { | ||
xml_set_processing_instruction_handler($parser, "nonexistent_method"); | ||
} catch (\Throwable $e) { | ||
echo $e::class, ': ', $e->getMessage(), PHP_EOL; | ||
} | ||
|
||
?> | ||
--EXPECT-- | ||
Invalid $parser: | ||
TypeError: xml_set_processing_instruction_handler(): Argument #1 ($parser) must be of type XMLParser, stdClass given | ||
Invalid callable type true: | ||
TypeError: xml_set_processing_instruction_handler(): Argument #2 ($handler) must be of type callable|string|null | ||
Invalid callable type int: | ||
TypeError: xml_set_processing_instruction_handler(): Argument #2 ($handler) must be of type callable|string|null | ||
String not callable and no object set: | ||
ValueError: xml_set_processing_instruction_handler(): Argument #2 ($handler) an object must be set via xml_set_object() to be able to lookup method | ||
String non existent method on set object: | ||
ValueError: xml_set_processing_instruction_handler(): Argument #2 ($handler) method stdClass::nonexistent_method() does not exist |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--TEST-- | ||
Test XMLParser generic handlers as trampoline callback | ||
--EXTENSIONS-- | ||
xml | ||
--FILE-- | ||
<?php | ||
class TrampolineTest { | ||
public function __call(string $name, array $arguments) { | ||
echo 'Trampoline for ', $name, PHP_EOL; | ||
echo 'Target: ', $arguments[1], PHP_EOL; | ||
echo 'Data: ', $arguments[2], PHP_EOL; | ||
} | ||
} | ||
|
||
$o = new TrampolineTest(); | ||
$callback = [$o, 'pi_handler']; | ||
|
||
$xml = <<<HERE | ||
<?xml version="1.0" encoding="ISO-8859-1"?> | ||
<?xml-stylesheet href="default.xsl" type="text/xml"?> | ||
HERE; | ||
|
||
/* Use xml_set_processing_instruction_handler() for generic implementation */ | ||
$parser = xml_parser_create(); | ||
xml_set_processing_instruction_handler($parser, $callback); | ||
xml_parse($parser, $xml, true); | ||
xml_parser_free($parser); | ||
|
||
?> | ||
--EXPECT-- | ||
Trampoline for pi_handler | ||
Target: xml-stylesheet | ||
Data: href="default.xsl" type="text/xml" |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.