php / php/php-src

Seralize incorrectly duplicates element in case of circular reference in array

Offen
#11,743 7 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bug Category: Serialization Status: Needs Triage
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.1k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

Description

The following code:

<?php

$a = ['id'=>1,'parent'=>null,'child'=>null];
$b = ['id'=>2,'parent'=>null,'child'=>null];
$a['child'] =&$b;
$b['parent'] = &$a;
echo serialize($a);

Resulted in this output:

a:3:{s:2:"id";i:1;s:6:"parent";N;s:5:"child";a:3:{s:2:"id";i:2;s:6:"parent";a:3:{s:2:"id";i:1;s:6:"parent";N;s:5:"child";R:4;}s:5:"child";N;}}

The problem is that in the 'child' array with id 2, 'parent' duplicates the root array with id 1 instead of directly referencing it, something along the lines of :

a:3:{s:2:"id";i:1;s:6:"parent";N;s:5:"child";a:3:{s:2:"id";i:2;s:6:"parent";R:1;s:5:"child";N;}}

In any case, the parent array shouldn't be duplicated, as this can cause traversal issues or modifications that won't properly propagate if code tries to modify the de-serialized array (for instance modifying element 2's parent will not propagate to the root as it should), for instance :

If I modify the original array :


$a['id'] = 3;
echo($a['id'].','.$a['child']['parent']['id']);

echoes (properly) :

3,3

However, if I unserialize the aformentioned string, and apply the same operation, it echoes :

3,1

The reference is lost, as is apparent from the serialized form.

(Of course this is a trivial example but corresponds to something I've encountered working with graph-type arrays)

PHP Version

PHP 8.1.21 (FPM,CLI)

Operating System

Debian 10 x64 (on WSL2 on Windows 10 x64) ; Debian 11 x64 (native)

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginnen Sie damit, den bereitgestellten PHP-Reproduzierer auszuführen und die serialisierte Ausgabe mit der erwarteten Form mit zirkulärer Referenz zu vergleichen. Verfolgen Sie das Verhalten der Array-Serialisierung und -Deserialisierung von PHP bei zirkulären Referenzen. Das Issue ist abgeschlossen, wenn das übergeordnete Array als Referenz erhalten bleibt und Änderungen daran nach der Deserialisierung an das Stammobjekt weitergegeben werden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
c, php
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
42/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.