7 Commits

Author SHA1 Message Date
Changjoon
175f12b664 Fix stack overflow on deeply-nested JSON in json.loads() (#7632)
* Fix stack overflow on deeply-nested JSON in json.loads()

json.loads() on a deeply-nested array or object payload (e.g.
'[' * 50000 + ']' * 50000) overflowed the native Rust stack and
crashed the interpreter process with SIGSEGV. CPython raises
RecursionError on the same input via _Py_EnterRecursiveCall in
Modules/_json.c.

The recursion lives in the mutual call chain:
  JsonScanner::parse_object / parse_array
    -> JsonScanner::call_scan_once
      -> JsonScanner::parse_object / parse_array

Every descent funnels through call_scan_once, so wrapping its body
with vm.with_recursion covers both '{' and '[' paths (and their
mixed nesting) with a single guard.

Before:
  ./rustpython -c "import json; json.loads('[' * 50000 + ']' * 50000)"
    -> SIGSEGV (exit 139)

After:
  -> RecursionError: maximum recursion depth exceeded while
     decoding a JSON object from a string

Verified:
  - extra_tests/snippets/stdlib_json.py: all assertions pass
    (includes 3 new regression cases: array, object, alternating
    nesting at depth 100000)
  - cargo run -- -m test test_json: 214 passed, 0 regressed
    (9 skipped, 13 expected failures, all pre-existing)
  - depth 500000 no longer crashes (RecursionError)
  - shallow parsing unchanged

* Enable test_highly_nested_objects_decoding

Per @ShaharNaveh's review on #7632: this test was previously marked
`@unittest.skip("TODO: RUSTPYTHON; crashes")` because json.loads
would SIGSEGV on the 500_000-deep input. The recursion-guard added
in this PR makes it raise RecursionError like CPython, so the skip
decorator can be removed.

  $ cargo run -- -m unittest \
        test.test_json.test_recursion.TestCRecursion.test_highly_nested_objects_decoding \
        test.test_json.test_recursion.TestPyRecursion.test_highly_nested_objects_decoding
  ...
  Ran 2 tests in 0.825s
  OK

  $ cargo run -- -m test test_json
  Ran 214 tests (7 skipped, 13 expected failures) — all pass.
2026-04-20 21:52:17 +09:00
ShaharNaveh
f73df6a102 Update test_json from 3.14.3 2026-02-10 21:00:40 +09:00
Lee Dogeon
5242ff5243 Bump json to 3.14.2 (#6774) 2026-01-18 19:16:48 +09:00
ShaharNaveh
a5b240aab8 skip crashing test 2025-07-25 16:13:07 +02:00
Shahar Naveh
c497061290 Update json from 3.13.5 (#6007)
* Update `json` from 3.13.5

* Update `test_json` from 3.13.5
2025-07-20 18:44:46 +09:00
CPython developers
413e8250f0 Update {test_}json from CPython 3.10.5 2022-07-19 01:33:15 +09:00
Noah
9d136d6450 Add test.test_json from CPython 3.8.2 2020-04-08 12:16:19 -05:00