File tree Expand file tree Collapse file tree 3 files changed +40
-1
lines changed
Expand file tree Collapse file tree 3 files changed +40
-1
lines changed Original file line number Diff line number Diff line change @@ -616,6 +616,9 @@ which the standard library allows, but is not valid JSON.
616616It raises ` JSONDecodeError ` if a combination of array or object recurses
6176171024 levels deep.
618618
619+ It raises ` JSONDecodeError ` if unable to allocate a buffer large enough
620+ to parse the document.
621+
619622` JSONDecodeError ` is a subclass of ` json.JSONDecodeError ` and ` ValueError ` .
620623This is for compatibility with the standard library.
621624
Original file line number Diff line number Diff line change @@ -50,7 +50,7 @@ const MINIMUM_BUFFER_CAPACITY: usize = 4096;
5050
5151fn buffer_capacity_to_allocate ( len : usize ) -> usize {
5252 // The max memory size is (json_size / 2 * 16 * 1.5 + padding).
53- ( ( ( len / 2 ) * 32 ) + 256 + ( MINIMUM_BUFFER_CAPACITY - 1 ) ) & !( MINIMUM_BUFFER_CAPACITY - 1 )
53+ ( ( ( len / 2 ) * 24 ) + 256 + ( MINIMUM_BUFFER_CAPACITY - 1 ) ) & !( MINIMUM_BUFFER_CAPACITY - 1 )
5454}
5555
5656fn unsafe_yyjson_is_ctn ( val : * mut yyjson_val ) -> bool {
@@ -73,6 +73,13 @@ pub(crate) fn deserialize(
7373 assume ! ( !data. is_empty( ) ) ;
7474 let buffer_capacity = buffer_capacity_to_allocate ( data. len ( ) ) ;
7575 let buffer_ptr = ffi ! ( PyMem_Malloc ( buffer_capacity) ) ;
76+ if unlikely ! ( buffer_ptr. is_null( ) ) {
77+ return Err ( DeserializeError :: from_yyjson (
78+ Cow :: Borrowed ( "Not enough memory to allocate buffer for parsing" ) ,
79+ 0 ,
80+ data,
81+ ) ) ;
82+ }
7683 let mut alloc = crate :: ffi:: yyjson:: yyjson_alc {
7784 malloc : None ,
7885 realloc : None ,
Original file line number Diff line number Diff line change 1+ # SPDX-License-Identifier: (Apache-2.0 OR MIT)
2+
3+ import os
4+
5+ import pytest
6+
7+ import orjson
8+
9+ ORJSON_RUNNER_MEMORY_GIB = os .getenv ("ORJSON_RUNNER_MEMORY_GIB" , "" )
10+
11+
12+ @pytest .mark .skipif (
13+ not ORJSON_RUNNER_MEMORY_GIB , reason = "ORJSON_RUNNER_MEMORY_GIB not defined"
14+ )
15+ def test_memory_loads ():
16+ buffer_factor = 12
17+ segment = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18+ size = (
19+ (int (ORJSON_RUNNER_MEMORY_GIB ) * 1024 * 1024 * 1024 )
20+ // buffer_factor
21+ // len (segment )
22+ )
23+ doc = "" .join ((segment for _ in range (0 , size )))
24+ with pytest .raises (orjson .JSONDecodeError ) as exc_info :
25+ _ = orjson .loads (doc )
26+ assert (
27+ str (exc_info .value )
28+ == "Not enough memory to allocate buffer for parsing: line 1 column 1 (char 0)"
29+ )
You can’t perform that action at this time.
0 commit comments