php / php/php-src

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

Ouverte
#10,104 6 commentaires 1 réaction 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Bug Extension: json Status: Needs Triage
Langage dominant
C
Étoiles
40.4k
Forks
8.2k
Merge moyen
2 j 13 h
PR mergées (30 j)
96

Description

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)

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.

Piste de recherche

Commencez par exécuter la reproduction fournie de json_decode() sur PHP 8.1.13, en faisant varier la profondeur d’imbrication et l’argument de profondeur maximale comme indiqué. Étudiez le comportement de l’analyseur pour des entrées profondément imbriquées d’environ 10 000 caractères ; le travail est terminé lorsque les entrées imbriquées valides sont décodées avec succès, tandis qu’une profondeur réellement excessive signale toujours l’erreur attendue de profondeur maximale de la pile.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
php
Domaine
backend
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

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