Skip to content

Regression: preg_*() /u on invalid UTF-8 — match succeeds, preg_last_error() stale (ext/pcre/php_pcre.c) #17503

Closed

Description

@PurHur

Category

Regression · php-src-strict

Problem

PCRE functions with the u (UTF-8) modifier must reject malformed subject strings: return false (or false from split) and set preg_last_error() to PREG_BAD_UTF8_ERROR (4). This compiler accepts invalid bytes and leaves preg_last_error() at 0.

Repro Zend 8.2+ VM (2026-07-09)
preg_match('//u', "\xFF") false; error 4 1; error 0
preg_split('//u', "\xFF") false; error 4 array(...); error 0
preg_replace('//u', 'x', "\xFF") false; error 4 mutates subject; error 0

php-src reference

PHP implementation target

  • ext/standard/ preg builtins + VM/JIT lowering — validate subject UTF-8 when pattern carries u; propagate preg_last_error() / preg_last_error_msg() like Zend
  • Prefer PHP implementation; keep any C as thin PCRE ABI only

Repro

./script/docker-exec.sh -- bash -lc '
php bin/vm.php test/repro/maintainer_gap_preg_match_invalid_utf8.php
php bin/vm.php test/repro/maintainer_gap_preg_split_invalid_utf8.php
'
# Zend: ok · VM: fail on both

Done when

  • preg_match, preg_match_all, preg_split, preg_replace, preg_grep with /u set PREG_BAD_UTF8_ERROR on invalid UTF-8 subjects (VM + JIT/AOT where pattern is known at compile time)
  • Compliance .phpt guards under test/compliance/cases/pcre/
  • 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 9, 2026
  2. PurHur commented on Jul 9, 2026

    @PurHur
    OwnerAuthor

    claim: cursor-agent-lane-b — starting this run

  3. PurHur commented on Jul 9, 2026

    @PurHur
    OwnerAuthor

    Merged via #17512.

    Fix: VmPregPure::ensureUtf8SubjectForOpts() validates subject UTF-8 when pattern has /u (PCRE2_UTF), sets PREG_BAD_UTF8_ERROR (4) like Zend ext/pcre/php_pcre.c.

    Verification (Docker):

    • php bin/vm.php test/repro/maintainer_gap_preg_match_invalid_utf8.php → false / error 4
    • php bin/vm.php test/repro/maintainer_gap_preg_split_invalid_utf8.php → false / error 4
    • php bin/vm.php test/compliance/cases/pcre/preg_utf8_invalid_subject.phpt — green
    • vendor/bin/phpunit --filter VmPregUtf8SubjectTest — 4/4 OK
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