php / php/php-src

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

オープン
#23,617 コメント 1 件 リアクション 0 件 担当者 1 名 GitHub で見る

@iliaal がすでに取り組んでいます。

2026年9月8日 から。

Bug Category: Engine Status: Verified
主要言語
C
スター
40.4k
フォーク
8.2k
平均マージ
2日 13時間
マージ済み PR(30日)
96

説明

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

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。