Skip to content

Regression: sprintf()/vsprintf(null) still coerce under PROFILE=8.4 (ext/standard/formatted_print.c) #20167

Closed

Description

@PurHur

Category

stdlib · php-src-strict · PHP 8.4 null→TypeError · ext/standard

Problem

Under PHP_COMPILER_PROFILE=8.4, sprintf('%s', null) and vsprintf('%s', [null]) still coerce null to '' and succeed. php-src 8.4 rejects null for typed string zpp value arguments with TypeError.

Repro (PROFILE=8.4) php-src 8.4 VM (2026-07-17)
sprintf('%s', null) TypeError ''
vsprintf('%s', [null]) TypeError ''

Open #8777 covers enum case operands for sprintf/printf/vsprintf — this issue is specifically null under the 8.4 forward profile.

php-src reference

PHP implementation target

  • ext/standard/sprintf.php / vsprintf.php (or shared formatted-print helper in ext/standard/)
  • Shared null guard used by other 8.4 string builtins (VmString::coerceZparamStrBuiltinArg family) when formatting consumes a string slot — PHP-in-PHP only, no new C

Repro

./script/docker-exec.sh -- bash -lc 'cat > /tmp/sprintf_null84.php <<'"'"'PHP'"'"'
<?php
foreach (["sprintf" => fn() => sprintf("%s", null), "vsprintf" => fn() => vsprintf("%s", [null])] as $n => $fn) {
  try { $r = $fn(); echo "$n COERCED ", var_export($r, true), "\n"; }
  catch (Throwable $e) { echo "$n ", get_class($e), "\n"; }
}
PHP
PHP_COMPILER_PROFILE=8.4 php bin/vm.php /tmp/sprintf_null84.php'

Expected: both TypeError. Today: COERCED ''.

Done when

  • sprintf('%s', null) / vsprintf('%s', [null]) throw TypeError under PHP_COMPILER_PROFILE=8.4 on VM
  • JIT/AOT agree when in scope
  • Compliance .phpt under test/compliance/cases/string/ or stdlib/
  • Default/8.2 profile still coerces like Zend 8.2
  • php-src-strict; no php-compiler-strict shortcut

Activity

  1. added
    bugSomething isn't working
    phase-4:stdlibPhase 4 – stdlib for web apps
    area:vmVirtual machine
    implementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claim
    on Jul 17, 2026
  2. PurHur commented on Jul 18, 2026

    @PurHur
    OwnerAuthor

    claim: PHP Compiler STD Lib — starting this run

    Trust probe (this workspace):

    • docker info OK; vendor present
    • php script/bootstrap-inventory.php --check — red: stale docs/bootstrap-inventory.md (ext/dom/VmDom.php method count 402→404; doc drift from recent DOM merges, not this issue)
    • ./script/release-readiness.sh --json — running

    Implementing sprintf/vsprintf null→TypeError under PROFILE=8.4 (php-src-strict).

  3. PurHur commented on Jul 18, 2026

    @PurHur
    OwnerAuthor

    Abandoning claim — php-src-strict mismatch on done-when

    Repro under Zend PHP 8.2.31 and this compiler (PHP_COMPILER_PROFILE=8.4):

    • sprintf('%s', null) / vsprintf('%s', [null]) → coerce to '' (no TypeError)
    • Format-arg sprintf(null) → deprecate + coerce (Z_PARAM_STR), not value-arg TypeError

    php-src / null_coercion_consistency RFC explicitly keeps sprintf('%s', NULL) coercing; value slots are not Z_PARAM_STR. Implementing TypeError here would diverge from Zend.

    Leaving open for maintainer retarget (e.g. format-arg 8.4 TypeError if that is the intent) or close as invalid.

  4. PurHur commented on Jul 21, 2026

    @PurHur
    OwnerAuthor

    Closing as invalid per prior investigation: php-src 8.4 does not throw TypeError for sprintf('%s', null) or vsprintf('%s', [null]). The variadic ...$values parameter uses Z_PARAM_VARIADIC('+', ...) (mixed), not Z_PARAM_STR. The %s conversion calls zval_get_string() which coerces null to "" — no deprecation, no TypeError.

    The null→TypeError deprecation path applies only to parameters declared with Z_PARAM_STR (typed string params), e.g. the format argument itself — which is already handled by VmString::stringBuiltinArgForFrame().

    Current VM behavior (sprintf('%s', null) → '') matches Zend 8.2 and 8.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:vmVirtual machinebugSomething isn't workingimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-4:stdlibPhase 4 – stdlib for web appsstdlib

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions