php / php/php-src

Internal pointer past the end resets to the first element on copy-on-write separation

Ouverte
#23,617 1 commentaire 0 réactions 1 personne assignée Voir sur GitHub

@iliaal y travaille déjà.

Depuis le 8/9/2026.

Bug Category: Engine Status: Verified
Langage dominant
C
Étoiles
40.4k
Forks
8.1k
Merge moyen
2 j 13 h
PR mergées (30 j)
96

Description

Description

end() followed by next() leaves the internal pointer past the end, so key() returns NULL. A copy-on-write separation then moves it back to the first element instead of leaving it past the end. An in-range pointer survives the same separation unchanged, and the untouched copy keeps NULL, so the past-the-end case is the only one that moves.

The following code:

<?php
$a = ['a' => 1, 'b' => 2, 'c' => 3];
end($a);
next($a);
var_dump(key($a), current($a));

$b = $a;
$a['d'] = 4;
var_dump(key($a), current($a));

Resulted in this output:

NULL
bool(false)
string(1) "a"
int(1)

But I expected this output instead:

NULL
bool(false)
NULL
bool(false)

zend_array_dup() clamps the copied pointer with (source->nInternalPointer < source->nNumUsed) ? source->nInternalPointer : 0 at Zend/zend_hash.c:2511 for the mixed case and :2495 for the packed case. The immutable branch at :2479 copies it verbatim, so the three arms of that function disagree.

PHP Version

PHP 8.4.25, also PHP-8.4 and master at d26d5f2

Operating System

Linux

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.