php / php/php-src

json_decode() fails on nested input of around 10000 characters.

Offen
#10,104 6 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bug Extension: json 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

function test($i, $s) {
  try {
    json_decode($s, false, 999999999, JSON_THROW_ON_ERROR);
    echo "Test $i passed\n";
  } catch (Exception $e) {
    echo "Test $i FAILED: $e\n";
  }
}

// String like [[[[...1...]]]] fails at length 9999, nesting depth 4999.
test(1, str_repeat('[', 4998) . '1' . str_repeat(']', 4998)); // pass
test(2, str_repeat('[', 4999) . '1' . str_repeat(']', 4999)); // FAIL

// String like [1,[1,[1,...1...]]] fails at length 10001, nesting depth 2499.
test(3, str_repeat('[1,', 2499) . '1' . str_repeat(']', 2499)); // pass
test(4, str_repeat('[1,', 2500) . '1' . str_repeat(']', 2500)); // FAIL

// Flat string like [[1],[1],[1]...] passes even at much greater length.
test(5, '[' . str_repeat('[1],', 9999) . '1]'); // pass

?>

Resulted in this output:

Test 1 passed
Test 2 FAILED: JsonException: Syntax error in json_decode_bug.php:5
Stack trace:
#0 json_decode_bug.php(5): json_decode()
#1 json_decode_bug.php(14): test()
#2 {main}
Test 3 passed
Test 4 FAILED: JsonException: Syntax error in json_decode_bug.php:5
Stack trace:
#0 json_decode_bug.php(5): json_decode()
#1 json_decode_bug.php(18): test()
#2 {main}
Test 5 passed

(I've removed the directory names from the stack trace for brevity.)

But I expected this output instead:

Test 1 passed
Test 2 passed
Test 3 passed
Test 4 passed
Test 5 passed

Note that the exception message ("Syntax error') is different from what I get when I reduce the maximum depth argument from 999999999 to 999. Then I get JsonException: Maximum stack depth exceeded instead (which is expected).

So it looks like the parser hits an undocumented limit when the input string reaches 10,000 characters, but only for the heavily-nested input.

PHP Version

PHP 8.1.13

Operating System

Arch Linux (x86_64)

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

Führen Sie zunächst die bereitgestellte json_decode()-Reproduktion auf PHP 8.1.13 aus und variieren Sie dabei die Verschachtelungstiefe sowie das Argument für die maximale Tiefe wie gezeigt. Untersuchen Sie das Parserverhalten bei tief verschachtelten Eingaben mit etwa 10.000 Zeichen; abgeschlossen ist die Aufgabe, wenn gültige verschachtelte Eingaben erfolgreich dekodiert werden, während eine tatsächlich übermäßige Tiefe weiterhin den erwarteten Fehler wegen der maximalen Stacktiefe meldet.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

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

Neue Issues direkt in Ihr Postfach

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