Skip to content

Stdlib: str_getcsv()/fgetcsv() — escape=enclosure " parses quoted fields wrong (ext/standard/file.c) #9303

Description

@PurHur

Category

stdlib · php-src-strict

Problem

When the CSV escape character equals the enclosure (", PHP 8.4+ default for str_getcsv() / fgetcsv()), this compiler stops parsing after the first field. Zend/php-src returns all fields with doubled-quote unescaping inside enclosures.

VM and JIT share ext/standard/VmCsv::parseLine() — one PHP fix covers all backends.

php-src reference

Repro

Run inside ./script/docker-exec.sh:

cat > /tmp/repro_csv_escape_quote.php <<'PHP'
<?php
$line = 'a,"b""c",d';
var_dump(str_getcsv($line, ',', '"', '"'));
$f = fopen('php://memory', 'r+');
fwrite($f, $line . "\n");
rewind($f);
var_dump(fgetcsv($f, 0, ',', '"', '"'));
fclose($f);
PHP
php /tmp/repro_csv_escape_quote.php
php bin/vm.php /tmp/repro_csv_escape_quote.php
Engine str_getcsv(..., '"', '"')
Zend PHP 8.2+ ['a', 'b"c', 'd']
VM (today) ['a']

Verified 2026-06-17.

Scope (PHP-in-PHP)

Layer Path
Parser SSOT ext/standard/VmCsv.php — fix doubled-enclosure branch when $esc === $enc
VM ext/standard/str_getcsv.php, ext/standard/fgetcsv.php (delegate to VmCsv)
JIT/AOT lib/JIT/Builtin/StringStrGetcsvJit.php, StringFgetcsvJit.php (reuse VmCsv)
Tests test/compliance/cases/stdlib/str_getcsv_escape_enclosure.phpt

No new C runtime — parser logic stays in PHP (VmCsv).

Done when (php-src-strict)

  • Repro returns ['a', 'b"c', 'd'] on VM and JIT/AOT
  • Backslash escape ('\\') path unchanged
  • Compliance PHPT green in Docker
  • Capability matrix unchanged (functions already registered)

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 machineimplementation-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