fix: safely interpolate logger context values#10384
Conversation
Co-authored-by: John Paul E Balandan <[email protected]>
|
The safe interpolation behavior should be tested with the full PSR-3 variety: arrays, scalar values, |
|
I believe we already covered a fair number of cases, and the previous behavior when it comes to the strings has not changed. |
|
Hi! While working on this PR to fix logger interpolation issues, I noticed there is another pre-existing bug in the environment variable placeholders interpolation. When a log message contains multiple This is because the current code uses if (str_contains($message, 'env:')) {
preg_match('/env:[^}]+/', $message, $matches);
foreach ($matches as $str) {
$key = str_replace('env:', '', $str);
$replace["{{$str}}"] = $_ENV[$key] ?? 'n/a';
}
}We can fix this easily in if (str_contains($message, 'env:')) {
preg_match_all('/env:[^}]+/', $message, $matches);
foreach ($matches[0] as $str) {
$key = str_replace('env:', '', $str);
$replace["{{$str}}"] = $_ENV[$key] ?? 'n/a';
}
}Here is a test case verifying this behavior: public function testLogInterpolatesMultipleEnvironmentVars(): void
{
$config = new LoggerConfig();
$logger = new Logger($config);
Time::setTestNow('2023-11-25 12:00:00');
$_ENV['foo'] = 'bar';
$_ENV['baz'] = 'qux';
$expected = 'DEBUG - ' . Time::now()->format('Y-m-d') . ' --> Test message bar and qux';
$logger->log('debug', 'Test message {env:foo} and {env:baz}');
$logs = TestHandler::getLogs();
$this->assertCount(1, $logs);
$this->assertSame($expected, $logs[0]);
}Would you like to include this fix in this PR, or should I open a separate PR/issue for it? |
|
The following test cases fail under the current implementation of PR Test 1: Object Data Loss (
|
The multiple |
|
Thank you everyone for the reviews! |
Description
This PR fixes logger message interpolation so arbitrary PSR-3 context values do not raise PHP warnings or errors when used as placeholders.
Context values are now converted to safe strings before being passed to
strtr(). Arrays and Entities are rendered withprint_r()to match the logger's existing output style,Stringablevalues such asTimecontinue to use their string representation, and non-stringable objects/resources fall back to safe descriptive placeholders.Reported in: https://forum.codeigniter.com/showthread.php?tid=94242
Ref: https://www.php-fig.org/psr/psr-3/
Checklist: