php / php/php-src

Seralize incorrectly duplicates element in case of circular reference in array

Open
#11,743 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Category: Serialization Status: Needs Triage
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

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)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the provided PHP reproducer and comparing the serialized output with the expected circular-reference form. Trace PHP's array serialization and unserialization behavior for circular references; the issue is done when the parent array is preserved by reference and modifying it after unserialization propagates to the root.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, php
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.