Skip to content

Commit 1e4a14f

Browse files
skjnldsvbackportbot[bot]
authored andcommitted
fix(config): add null coalescing fallback in getValueBool before strtolower
Followup to #59646: guard against null reaching strtolower() in both AppConfig and UserConfig getValueBool(). Also aligns AppConfig with the (string) cast added in UserConfig by the original PR. Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
1 parent 908ebae commit 1e4a14f

3 files changed

Lines changed: 18 additions & 11 deletions

File tree

build/psalm-baseline.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3550,11 +3550,6 @@
35503550
<code><![CDATA[$CONFIG]]></code>
35513551
</UndefinedVariable>
35523552
</file>
3553-
<file src="lib/private/Config/UserConfig.php">
3554-
<RedundantCast>
3555-
<code><![CDATA[(string)$this->getTypedValue($userId, $app, $key, $default ? 'true' : 'false', $lazy, ValueType::BOOL)]]></code>
3556-
</RedundantCast>
3557-
</file>
35583553
<file src="lib/private/Console/Application.php">
35593554
<NoInterfaceProperties>
35603555
<code><![CDATA[$this->request->server]]></code>

lib/private/AppConfig.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,15 @@ public function getValueFloat(string $app, string $key, float $default = 0, bool
437437
*/
438438
#[\Override]
439439
public function getValueBool(string $app, string $key, bool $default = false, bool $lazy = false): bool {
440-
$b = strtolower($this->getTypedValue($app, $key, $default ? 'true' : 'false', $lazy, self::VALUE_BOOL));
440+
// The explicit (string) cast and ?? null guard defend against a PHP OPcache bug where
441+
// values passed by reference across function boundaries can have their type corrupted
442+
// (e.g. bool returned as int, or null). Affects PHP 8.x with OPcache enabled; fixed
443+
// upstream in https://github.com/php/php-src/pull/21973. Keep until minimum PHP version
444+
// is bumped. Psalm sees the declared return type (string) and flags these as redundant.
445+
/** @psalm-suppress RedundantCondition, TypeDoesNotContainNull */
446+
$value = $this->getTypedValue($app, $key, $default ? 'true' : 'false', $lazy, self::VALUE_BOOL) ?? ($default ? 'true' : 'false');
447+
/** @psalm-suppress RedundantCast */
448+
$b = strtolower((string)$value);
441449
return in_array($b, ['1', 'true', 'yes', 'on']);
442450
}
443451

lib/private/Config/UserConfig.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -705,11 +705,15 @@ public function getValueBool(
705705
bool $default = false,
706706
bool $lazy = false,
707707
): bool {
708-
// The explicit (string) cast guards against a PHP OPcache bug where values passed
709-
// by reference across function boundaries can have their type corrupted (e.g. bool
710-
// returned as int). Affects PHP 8.x with OPcache enabled; fixed upstream in
711-
// https://github.com/php/php-src/pull/21973. Keep until minimum PHP version is bumped.
712-
$b = strtolower((string)$this->getTypedValue($userId, $app, $key, $default ? 'true' : 'false', $lazy, ValueType::BOOL));
708+
// The explicit (string) cast and ?? null guard defend against a PHP OPcache bug where
709+
// values passed by reference across function boundaries can have their type corrupted
710+
// (e.g. bool returned as int, or null). Affects PHP 8.x with OPcache enabled; fixed
711+
// upstream in https://github.com/php/php-src/pull/21973. Keep until minimum PHP version
712+
// is bumped. Psalm sees the declared return type (string) and flags these as redundant.
713+
/** @psalm-suppress RedundantCondition, TypeDoesNotContainNull */
714+
$value = $this->getTypedValue($userId, $app, $key, $default ? 'true' : 'false', $lazy, ValueType::BOOL) ?? ($default ? 'true' : 'false');
715+
/** @psalm-suppress RedundantCast */
716+
$b = strtolower((string)$value);
713717
return in_array($b, ['1', 'true', 'yes', 'on']);
714718
}
715719

0 commit comments

Comments
 (0)