Skip to content

Regression: DOMText::length / DOMNode::childNodes — fatal Variable uninitialized (ext/dom/text.c, node.c) #17722

Closed

Description

@PurHur

Category

stdlib · php-src-strict

Problem

Reading common DOM live properties (DOMText::$length, DOMNode::$childNodes on empty nodes) must return Zend values. VM fatals with Typed property PHPCompiler\VM\Variable::$string must not be accessed before initialization during property_exists() / property reads — enum/const materialization touches uninitialized Variable slots.

Repro Zend 8.2+ VM (2026-07-10)
(new DOMDocument())->createTextNode('hi')->length 2 Fatal Variable::$string uninitialized
(new DOMDocument())->childNodes->length on empty doc 0 (OK) Fatal Variable::$string uninitialized

php-src reference

PHP implementation target

  • ext/dom/VmDom.php — lazy length / childNodes property handlers without tripping ClassConstMaterializer on DOM object graphs
  • lib/VM/Variable.php / lib/VM/ClassConstMaterializer.php — ensure property_exists() on DOM instances does not materialize enum constants with uninitialized typed slots

Repro

./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_dom_text_length.php'
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_dom_childnodes_empty.php'

Done when

  • Both repros match Zend output (true/2/'hi'/8/4 and OK)
  • Compliance .phpt guards under test/compliance/cases/dom/
  • php-src-strict; no php-compiler-strict shortcut

Activity

  1. added
    bugSomething isn't working
    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 Jul 10, 2026
  2. PurHur commented on Jul 10, 2026

    @PurHur
    OwnerAuthor

    claim: PHP Compiler Ext — DOM & XML — starting this run

  3. PurHur commented on Jul 10, 2026

    @PurHur
    OwnerAuthor

    Merged via #17733

    Root cause: #17676 (ee3efc36a) routed runtime global assigns through deep detachConstantValue, which read uninitialized ext/dom typed property prototypes (TYPE_STRING slots) when script-scope variables like $doc = new DOMDocument() were stored.

    Fix: materializeGlobalVariableValue() keeps live object identity for runtime globals; detachConstantValue() skips uninitialized typed slots.

    Verification:

    source script/php-env.sh
    php bin/vm.php test/repro/maintainer_gap_dom_text_length.php   # true/2/'hi'/8/4
    php bin/vm.php test/repro/maintainer_gap_dom_childnodes_empty.php  # OK
    php bin/jit.php test/repro/maintainer_gap_dom_text_length.php
    vendor/bin/phpunit test/unit/DomModuleTest.php --no-configuration  # OK (28, 2 skipped)
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 workingenhancementNew feature or requestimplementation-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