-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Fix GH-23204: use-after-free when __toString() destroys an array argument #23207
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
Changes from all commits
6c2ad99
127f016
b9443b8
36daac5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| --TEST-- | ||
| GH-23204 (Use-after-free when __toString() destroys the array being read) | ||
| --CREDITS-- | ||
| e1abrador | ||
| --FILE-- | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please credit the reporter within
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added, credited as
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not me, @e1abrador.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The docs say the CREDITS section should no longer be used. Should the wording be extended with a "unless reporters have to be credited"?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My mistake, sorry. Changed to
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The reasoning behind this is that git commits can track authors via Co-authored-by, which is complete bs. CREDITS section is a much more precise indication of authorship than a commit-wide author tag. So I purposefully ignore that docs and I believe that line should be removed.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like that this paragraph of the docs is only considering the case of the commit authors crediting themselves. It makes sense to me that no CREDITS section should be used in this case. We could expand this paragraph with the case of committing a reproducer that was contributed by someone else.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I proposed a change in #23215 |
||
| <?php | ||
| class Unset_ implements Stringable { | ||
| public function __toString(): string { | ||
| global $a; | ||
| $a = null; | ||
| return "X"; | ||
| } | ||
| } | ||
|
|
||
| $a = [new Unset_, 2, 3, 4]; | ||
| echo "destroyed: ", implode(",", $a), "\n"; | ||
| var_dump($a); | ||
|
|
||
| class Append implements Stringable { | ||
| public function __toString(): string { | ||
| global $b; | ||
| $b[] = str_repeat("y", 32); | ||
| return "X"; | ||
| } | ||
| } | ||
|
|
||
| $b = [new Append, 2, 3, 4]; | ||
| echo "appended: ", implode(",", $b), "\n"; | ||
| echo "count: ", count($b), "\n"; | ||
|
|
||
| class Boom implements Stringable { | ||
| public function __toString(): string { | ||
| global $c; | ||
| $c = null; | ||
| throw new Exception("boom"); | ||
| } | ||
| } | ||
|
|
||
| $c = [new Boom, 2, 3, 4]; | ||
| try { | ||
| implode(",", $c); | ||
| } catch (Exception $e) { | ||
| echo $e::class, ': ', $e->getMessage(), "\n"; | ||
| } | ||
|
|
||
| class UnsetPats implements Stringable { | ||
| public function __toString(): string { | ||
| global $d; | ||
| $d = null; | ||
| return "X"; | ||
| } | ||
| } | ||
|
|
||
| $d = ["aa" => new UnsetPats, "bb" => "2", "cc" => "3", "dd" => "4"]; | ||
| echo "strtr: ", strtr("aabbccdd", $d), "\n"; | ||
|
|
||
| $e = ["aa" => new UnsetPats]; | ||
| $d = &$e; | ||
| echo "strtr single: ", strtr("aabb", $e), "\n"; | ||
|
|
||
| class UnsetSearch implements Stringable { | ||
| public function __toString(): string { | ||
| global $f; | ||
| $f = null; | ||
| return "a"; | ||
| } | ||
| } | ||
|
|
||
| $f = [new UnsetSearch, "b", "c", "d"]; | ||
| echo "str_replace search: ", str_replace($f, "z", "abcd"), "\n"; | ||
|
|
||
| class UnsetReplace implements Stringable { | ||
| public function __toString(): string { | ||
| global $g; | ||
| $g = null; | ||
| return "z"; | ||
| } | ||
| } | ||
|
|
||
| $g = [new UnsetReplace, "y", "y", "y"]; | ||
| echo "str_replace replace: ", str_replace(["a", "b", "c", "d"], $g, "abcd"), "\n"; | ||
|
|
||
| class UnsetSubject implements Stringable { | ||
| public function __toString(): string { | ||
| global $h; | ||
| $h = null; | ||
| return "abcd"; | ||
| } | ||
| } | ||
|
|
||
| $h = [new UnsetSubject, "abcd"]; | ||
| var_dump(str_replace("a", "z", $h)); | ||
| ?> | ||
| --EXPECT-- | ||
| destroyed: X,2,3,4 | ||
| NULL | ||
| appended: X,2,3,4 | ||
| count: 5 | ||
| Exception: boom | ||
| strtr: X234 | ||
| strtr single: Xbb | ||
| str_replace search: zzzz | ||
| str_replace replace: zyyy | ||
| array(2) { | ||
| [0]=> | ||
| string(4) "zbcd" | ||
| [1]=> | ||
| string(4) "zbcd" | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.