Category
language · php-src-strict · Pillar 4 Correctness · (re-#15036 / #3351)
Problem
Under current master, Exception::getTrace() for a frame whose callee has #[\SensitiveParameter] returns zero args (argc=0). Zend/php-src keeps the argument vector and replaces sensitive parameters with SensitiveParameterValue objects (non-sensitive args remain visible). Prior #15036 closed after omitting args entirely — that is not php-src-strict.
Probed 2026-07-20 via ./script/docker-exec.sh vs php:8.4-cli.
function f(#[\SensitiveParameter] string $password, string $ok) {
throw new Exception('boom');
}
try { f('secret', 'visible'); } catch (Throwable $e) {
// inspect $e->getTrace()[0]['args']
}
| Repro |
Zend 8.4 |
VM PROFILE=8.4 (2026-07-20) |
count($trace[0]['args']) |
2 |
0 |
$args[0] |
SensitiveParameterValue |
(missing) |
$args[1] |
'visible' |
(missing) |
str_contains($e->getTraceAsString(), 'secret') |
false |
false |
str_contains($e->getTraceAsString(), 'SensitiveParameterValue') |
true |
false |
php-src reference
PHP implementation target
- Restore/adjust trace building in VM (+ JIT/AOT if shared) so sensitive params become
SensitiveParameterValue instead of dropping the entire args array
- Keep non-sensitive args intact; never leak raw sensitive scalars in
getTraceAsString()
- Reuse existing
VmSensitiveParam / attribute metadata paths (#10394 lineage); PHP-in-PHP — no new runtime/*.c
Repro
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && PHP_COMPILER_PROFILE=8.4 php bin/vm.php -r '\''
function f(#[\SensitiveParameter] string $password, string $ok) { throw new Exception("boom"); }
try { f("secret", "visible"); } catch (Throwable $e) {
$a = $e->getTrace()[0]["args"] ?? [];
echo "argc=", count($a), "\n";
echo "a0=", isset($a[0]) && is_object($a[0]) ? get_class($a[0]) : "missing", "\n";
echo "a1=", isset($a[1]) ? var_export($a[1], true) : "missing", "\n";
}
'\'''
Done when
Category
language· php-src-strict · Pillar 4 Correctness · (re-#15036 / #3351)Problem
Under current master,
Exception::getTrace()for a frame whose callee has#[\SensitiveParameter]returns zero args (argc=0). Zend/php-src keeps the argument vector and replaces sensitive parameters withSensitiveParameterValueobjects (non-sensitive args remain visible). Prior #15036 closed after omitting args entirely — that is not php-src-strict.Probed 2026-07-20 via
./script/docker-exec.shvsphp:8.4-cli.count($trace[0]['args'])20$args[0]SensitiveParameterValue$args[1]'visible'str_contains($e->getTraceAsString(), 'secret')falsefalsestr_contains($e->getTraceAsString(), 'SensitiveParameterValue')truefalsephp-src reference
Zend/zend_exceptions.c— trace arg redactionZend/zend_builtin_functions.c—SensitiveParameterValue#[\SensitiveParameter]on parametersPHP implementation target
SensitiveParameterValueinstead of dropping the entireargsarraygetTraceAsString()VmSensitiveParam/ attribute metadata paths (#10394lineage); PHP-in-PHP — no newruntime/*.cRepro
Done when
getTrace()[0]['args']has arity matching the call; sensitive slots areSensitiveParameterValue; others unchangedgetTraceAsString()showsSensitiveParameterValue(or equivalent Zend formatting) and never the raw secret.phptundertest/compliance/cases/(attributes/exceptions)