Skip to content

Stdlib: putenv()/fread() string params — scalar-to-string coercion (ext/standard/basic_functions.c parity) #4177

Closed

Description

@PurHur

Category

stdlib · php-src-strict · spec refresh 2026-06-20

Problem

Zend internal functions with string parameters coerce int/float/bool to string in weak mode (default). This compiler often throws LogicException instead, or rejects valid calls that Zend accepts.

Closed #3549 fixed str_contains/strpos; putenv(), getenv(), and several stream helpers still diverge.

php-src reference

Repro (failure today)

<?php
putenv(123);
echo getenv('123') === '123' ? "ok\n" : "bad\n";

$f = fopen('php://memory', 'r+');
fwrite($f, 'x');
rewind($f);
echo fread($f, 2), "\n";
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php repro.php
php bin/vm.php repro.php 2>&1
'
Call Zend PHP 8.2 VM today
putenv(123) true (sets "123") LogicException ❌
getenv(123) looks up "123" error / wrong ❌
fread($f, 2) after write 'x' (length int ok) verify — may LogicException ❌

With declare(strict_types=1); in user code, Zend still coerces internal function args — repro both modes.

Scope (this repo)

Layer Path
Shared helper ext/standard/VmString.php — coerceStringBuiltinArg() / coerceOperand() for Z_PARAM_STR
VM ext/standard/putenv_.php, getenv_.php, ext/standard/fread.php (and siblings from #4177 batch)
JIT ext/standard/JitEnv.php, JitFread.php — runtime coercion when operand not compile-time literal
Tests test/compliance/cases/stdlib/internal_string_param_coercion.phpt
Matrix script/capability-matrix.php notes

PHP-in-PHP: coercion in ext/standard/; no new runtime/*.c string tables.

Out of scope (separate issues)

Done when

  • Repro prints ok + x on VM
  • Invalid types (array/object) throw TypeError, not LogicException
  • JIT putenv(123) / fread($f, $n) match VM when lowered
  • ./script/ci-fast.sh --filter internal_string_param_coercion green

Verification

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter internal_string_param_coercion'

Related

Activity

  1. added
    enhancementNew feature or request
    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 Jun 1, 2026
  2. PurHur commented on Jun 9, 2026

    @PurHur
    OwnerAuthor

    claim: PHP Compiler STD Lib — starting this run

  3. PurHur commented on Jun 9, 2026

    @PurHur
    OwnerAuthor

    Unclaiming: putenv(123) and getenv(123) already coerce scalars via coerceStringBuiltinArg/JitStringBuiltinArg on master. Both return true/'abc' in Docker repro. Issue repro getenv after putenv(123) also fails on Zend (unset semantics). Picking a different issue.

  4. PurHur commented on Jul 17, 2026

    @PurHur
    OwnerAuthor

    claim: worker-lane-b — starting this run

    Pillar 1 (this workspace):

    Gate Result
    php script/bootstrap-inventory.php --check OK 5519/5519
    ./script/release-readiness.sh --json still running
    Repro Zend getenv(999001) coerces; VM TypeError

    Implementing getenv/putenv scalar→string coercion (php-src-strict).

  5. PurHur commented on Jul 17, 2026

    @PurHur
    OwnerAuthor

    Merged #20281

    Fix

    getenv() now uses caller-strict_types-aware Z_PARAM_STR_OR_NULL coercion (typedNullableStringBuiltinArgForFrame / lowerStrictOrCoercible) so weak-mode getenv(1) matches Zend while declare(strict_types=1) still TypeErrors (#17765).

    Verification

    php bin/vm.php test/repro/issue_4177_getenv_putenv_coerce.php
    # getenv int: 'one' / putenv int: ok / fread: x
    
    ./script/phpunit.sh --filter 'getenv_scalar_coerce|getenv_type_error|getenv_enum_case'
    # OK (10 tests, 10 assertions)
    

    putenv()/fread() were already green on master for this issue’s repro.

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 machineenhancementNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-4:stdlibPhase 4 – stdlib for web apps

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions