fix: env() TypeError for non-string $_SERVER values + esc() fixes#10305
Open
gr8man wants to merge 1 commit into
Open
fix: env() TypeError for non-string $_SERVER values + esc() fixes#10305gr8man wants to merge 1 commit into
gr8man wants to merge 1 commit into
Conversation
- env(): guard non-string values (int argc, array argv in CLI) before strtolower() to prevent TypeError under declare(strict_types=1) - esc(): propagate $encoding in recursive array calls (was ignored before), add early return after array processing, replace single static $escaper with static $escapers[] cache keyed by encoding - tests: data-provider test for env() non-string types, three tests for esc() foreach reference leak
53a365d to
449dbae
Compare
michalsn
requested changes
Jun 12, 2026
michalsn
left a comment
Member
There was a problem hiding this comment.
Please send one change per PR.
This needs a changelog entry.
| $value = esc($value, $context); | ||
| $value = esc($value, $context, $encoding); | ||
| } | ||
| unset($value); // Prevent reference leak: &$value would remain bound to last element |
Member
There was a problem hiding this comment.
Suggested change
| unset($value); // Prevent reference leak: &$value would remain bound to last element |
What reference leak? We return right after this.
| $escaper = new Escaper($encoding); | ||
| } | ||
| static $escapers = []; | ||
| $cacheKey = $encoding ?? 'default'; |
Member
There was a problem hiding this comment.
This will cause the incorrect encoding default to be accepted after the first normal instantiation.
Please change it to the equivalent of Escaper handling:
Suggested change
| $cacheKey = $encoding ?? 'default'; | |
| $cacheKey = strtolower($encoding ?? 'utf-8'); |
michalsn
reviewed
Jun 12, 2026
Comment on lines
+315
to
+344
| public function testEscapeArrayDoesNotLeakForeachReference(): void | ||
| { | ||
| $data = ['first' => '<b>bold</b>', 'last' => '<i>italic</i>']; | ||
|
|
||
| $escaped = esc($data); | ||
|
|
||
| $this->assertSame('<b>bold</b>', $escaped['first']); | ||
| $this->assertSame('<i>italic</i>', $escaped['last']); | ||
| } | ||
|
|
||
| public function testEscapeArrayLastElementNotMutatedAfterCall(): void | ||
| { | ||
| $data = ['x' => '<script>', 'y' => '<style>']; | ||
|
|
||
| $escaped = esc($data); | ||
|
|
||
| $this->assertSame('<script>', $escaped['x']); | ||
| $this->assertSame('<style>', $escaped['y']); | ||
| $this->assertCount(2, $escaped); | ||
| } | ||
|
|
||
| public function testEscapeArrayReferenceIsCleanedUpOnSingleElement(): void | ||
| { | ||
| $data = ['only' => '<div>']; | ||
|
|
||
| $escaped = esc($data); | ||
|
|
||
| $this->assertSame('<div>', $escaped['only']); | ||
| } | ||
|
|
Member
There was a problem hiding this comment.
Suggested change
| public function testEscapeArrayDoesNotLeakForeachReference(): void | |
| { | |
| $data = ['first' => '<b>bold</b>', 'last' => '<i>italic</i>']; | |
| $escaped = esc($data); | |
| $this->assertSame('<b>bold</b>', $escaped['first']); | |
| $this->assertSame('<i>italic</i>', $escaped['last']); | |
| } | |
| public function testEscapeArrayLastElementNotMutatedAfterCall(): void | |
| { | |
| $data = ['x' => '<script>', 'y' => '<style>']; | |
| $escaped = esc($data); | |
| $this->assertSame('<script>', $escaped['x']); | |
| $this->assertSame('<style>', $escaped['y']); | |
| $this->assertCount(2, $escaped); | |
| } | |
| public function testEscapeArrayReferenceIsCleanedUpOnSingleElement(): void | |
| { | |
| $data = ['only' => '<div>']; | |
| $escaped = esc($data); | |
| $this->assertSame('<div>', $escaped['only']); | |
| } |
There is no reference leak, so these tests don't prove anything IMO.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fix:
env()TypeError in CLI +esc()improvementsWhat
Fixes two bugs in
system/Common.php.env()— In CLI,$_SERVERcontains non-string values (argcisint,argvisarray). Passing them tostrtolower()threw aTypeErrorunderdeclare(strict_types=1). Added anis_string()guard before thematchexpression; non-string values are returned as-is.esc()— Three fixes applied together:foreach ($data as &$value)left a dangling reference after the loop; addedunset($value)to prevent silent mutation of the last array element in the calling scope$encodingwas not propagated in recursive array callsstatic $escaperwithstatic $escapers[]keyed by encoding for correct per-encoding cachingTests
Added a data-provider test for
env()covering non-string$_SERVER/$_ENVvalues (int, array, float), and three tests verifying theesc()reference leak is gone.Files changed
system/Common.phptests/system/CommonFunctionsTest.php