Skip to content

Stdlib: filesystem path builtins — enum path operands must TypeError (ext/standard/filestat.c) #5735

Description

@PurHur

Category

stdlib

Problem

Several path-string builtins accept enum case operands on VM (treating them as paths or coercing silently) while Zend throws TypeError. php-src-strict: reject TYPE_ENUM_CASE before any path coercion — never pass backing string/name to open()/stat().

Phase 1 (this issue): read/stat family below. Phase 2: #6205 (filesize, disk_*, chmod, touch, fopen, …). Phase 3: #6280 / #6266 (copy, rename, link, …).

php-src reference

Repro (verified 2026-06-05)

<?php
enum PathEnum: string { case A = 'x'; }
enum UnitEnum { case A; }

$fns = [
    'file_get_contents', 'file_exists', 'is_file', 'is_dir', 'is_link',
    'is_readable', 'is_writable', 'is_executable', 'unlink', 'mkdir', 'rmdir',
];
foreach ($fns as $fn) {
    if (!function_exists($fn)) {
        echo "{$fn} missing\n";
        continue;
    }
    try {
        $fn(PathEnum::A);
        echo "{$fn} ok\n";
    } catch (Throwable $e) {
        echo "{$fn} " . $e::class . ': ' . $e->getMessage() . "\n";
    }
}
docker info >/dev/null
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php repro.php
php bin/vm.php repro.php
'
Function Zend PHP 8.2 bin/vm.php (today)
file_get_contents TypeError succeeds ❌
file_exists TypeError succeeds ❌
is_file TypeError succeeds ❌
is_dir TypeError succeeds ❌
unlink TypeError succeeds ❌
mkdir TypeError succeeds ❌

Use backed and unit enum cases in compliance .phpt; message must name enum class (not "string expected").

Scope (PHP-in-PHP)

Layer Path
VM shared guard ext/standard/VmString.phpcoerceStringBuiltinArg() / new rejectEnumCasePathArg() before IO
Per-builtin ext/standard/file_get_contents.php, file_exists.php, is_*.php, unlink.php, mkdir.php, …
JIT JitFileGetContents.php, JitFileExists.php, … — emit TypeError before phpc_fs_dir.c / stream helpers
C shrink Keep phpc_fs_dir.c thin per #5459; guards live in PHP lowering

Mirror #5780 hash enum guard pattern for VM + JIT + AOT when touched.

Done when

  • Repro: every registered function in the table throws TypeError on VM (skip missing with note in PR)
  • test/compliance/cases/stdlib/fs_path_enum_operand.phpt — VM + JIT rows when lowered
  • No host open()/stat() on coerced enum backing values
  • ./script/ci-fast.sh --filter fs_path_enum_operand green

Verification

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

Related

Activity

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