ArrayObject backing storage cycle causes unbounded recursion in spl_array_get_hash_table_ptr()

Abierto
#24,615 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
1-2 días
Aptitud para principiantes
51/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
c, php
Área
backend, devtools

Línea de trabajo

Start in ext/spl/spl_array.c, especially spl_array_set_array() and spl_array_get_hash_table_ptr(), and trace how SPL_ARRAY_USE_OTHER follows ArrayObject or ArrayIterator backing storage. Check existing SPL tests for exchangeArray() and constructor behavior, then add coverage showing that creating a multi-object backing cycle raises an error without recursion; verify ordinary backing objects still work.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Description

ArrayObject::exchangeArray() (and the constructor) accept another ArrayObject as backing storage and only reject an object backing itself. Two objects that back each other are accepted silently, and the first operation that needs the storage recurses without limit in spl_array_get_hash_table_ptr() until the process crashes.

The following code:

<?php
$a = new ArrayObject([1]);
$b = new ArrayObject($a);   // $b uses $a's storage
$a->exchangeArray($b);      // $a now uses $b's storage: a cycle
echo "cycle built\n";
var_dump(count($a));

Resulted in this output (AddressSanitizer build):

==ERROR: AddressSanitizer: stack-overflow on address ...
    #0 spl_array_get_hash_table_ptr ext/spl/spl_array.c:65
    #1 spl_array_get_hash_table_ptr ext/spl/spl_array.c:71
    #2 spl_array_get_hash_table_ptr ext/spl/spl_array.c:71
    ...

But I expected this output instead: an error when the cycle is created (for example an InvalidArgumentException from exchangeArray()), as for other unsupported backing objects.

spl_array_set_array() sets SPL_ARRAY_USE_OTHER for any other ArrayObject/ArrayIterator and only special-cases Z_OBJ_P(object) == Z_OBJ_P(array); following the chain of SPL_ARRAY_USE_OTHER objects before accepting one would catch longer cycles too. Object backing storage is deprecated on master, but it is still accepted there.

Reproduced on 8.2.34-dev (512c04e39f) and 8.4.28-dev; the same code is on master.

This issue was found by an LLM-Enhanced Static Analysis Engine and verified manually.

PHP Version
PHP 8.4.28-dev, PHP 8.2.34-dev
Operating System

Linux (Ubuntu 20.04, x86_64)

Lenguaje dominante
C
Estrellas
41.8k
Forks
8.5k
Merge medio
2 d 13 h
PR fusionados (30 d)
145

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de php/php-src

Todos los issues de php/php-src

Issues similares

Más issues de C

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.