Skip to content

Stdlib: iterator_to_array() accepts array keys as "Array" — Zend TypeError Illegal offset type (ext/spl/iterator.c) #23573

Closed

Description

@PurHur

Category

bug · php-src-strict · stdlib · iterator_to_array / MultipleIterator

Problem

When an iterator yields an array key (e.g. MultipleIterator with MIT_KEYS_ASSOC / MIT_KEYS_NUMERIC), Zend iterator_to_array() throws TypeError: Illegal offset type. The VM coerces the key to the string "Array" and returns a one-element array (last row only) — silent wrong result.

foreach over the same MultipleIterator correctly yields array keys on both Zend and VM; the gap is specifically materializing those keys into a PHP array.

Verified 2026-07-26 (host Zend 8.2.32 vs php bin/vm.php):

Repro Zend VM
foreach (MultipleIterator… as $k=>$v) $k is array $k is array
iterator_to_array($m) TypeError: Illegal offset type ['Array' => last value]

php-src reference

  • php/php-src ext/spl/spl_iterators.c — iterator_to_array / spl_iterator_to_array_apply (array key → illegal offset)
  • MultipleIterator key shape: same tree — MIT_KEYS_ASSOC / MIT_KEYS_NUMERIC

PHP implementation target

  • lib/VM.php — iterator_to_array materialization must TypeError on non-int/non-string keys (reuse HashTable::normalizeIndexKey / EnumCaseSupport::rejectIllegalArrayOffset patterns already used elsewhere)
  • Do not special-case MultipleIterator only — any Traversable with array/object keys should match Zend
  • PHP-in-PHP; no new C runtime

Repro

./script/docker-exec.sh -- bash -lc 'cat > /tmp/ita_akey.php <<'\''PHP'\''
<?php
$m = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$m->attachIterator(new ArrayIterator([10, 20]), "a");
$m->attachIterator(new ArrayIterator([30, 40]), "b");
try {
    var_export(iterator_to_array($m));
    echo "\n";
} catch (Throwable $e) {
    echo get_class($e), ":", $e->getMessage(), "\n";
}
PHP
php /tmp/ita_akey.php; php bin/vm.php /tmp/ita_akey.php'

Done when

  • iterator_to_array on MultipleIterator (ASSOC and NUMERIC key modes) throws TypeError: Illegal offset type like Zend
  • foreach over the same iterators still yields array keys correctly
  • Compliance .phpt guard under test/compliance/cases/stdlib/ (or SPL)
  • 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 26, 2026
  2. PurHur commented on Jul 26, 2026

    @PurHur
    OwnerAuthor

    claim: PHP Compiler STD Lib Advanced — batch (issues #23552, #23431, #23565, #23511, #23572, #23573)

    Working #23552 first (array_walk object visibility + mangling; also covers #23431 done-when). Sequential PRs; merge before next.

  3. PurHur commented on Jul 26, 2026

    @PurHur
    OwnerAuthor

    Merged #23617

    Verification: Zend + VM issue repro both TypeError:Illegal offset type; phpunit --filter iterator_to_array_illegal_offset_type OK (2 tests).

    Fix: appendHashTableEntry uses HashTable::normalizeIndexKey so array/object/enum keys reject instead of coercing to "Array".

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