php / php/php-src

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

Đang mở
#10,104 6 bình luận 1 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Bug Extension: json Status: Needs Triage
Ngôn ngữ chính
C
Star
40.4k
Fork
8.1k
Merge trung bình
2 ngày 13 giờ
Pull request đã merge (30 ngày)
96

Mô tả

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)

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu bằng cách chạy bản tái hiện json_decode() được cung cấp trên PHP 8.1.13, thay đổi độ sâu lồng nhau và đối số độ sâu tối đa như được minh họa. Điều tra hành vi của parser đối với các đầu vào lồng nhau sâu khoảng 10.000 ký tự; được xem là hoàn tất khi các đầu vào lồng nhau hợp lệ được giải mã thành công, trong khi độ sâu thực sự quá mức vẫn báo lỗi độ sâu ngăn xếp tối đa như mong đợi.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
php
Lĩnh vực
backend
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.