4646# pragma warning(disable:4101) /* unreferenced variable */
4747# pragma warning(disable:4102) /* unreferenced label */
4848# pragma warning(disable:4127) /* conditional expression is constant */
49+ # pragma warning(disable:4702) /* unreachable code */
4950# pragma warning(disable:4706) /* assignment within conditional expression */
5051#endif
5152
@@ -338,8 +339,9 @@ uint32_t yyjson_version(void) {
338339#ifndef YYJSON_DISABLE_UTF8_VALIDATION
339340#define YYJSON_DISABLE_UTF8_VALIDATION 0
340341#endif
341-
342-
342+ #ifndef YYJSON_READER_DEPTH_LIMIT
343+ #define YYJSON_READER_DEPTH_LIMIT 0
344+ #endif
343345
344346/*==============================================================================
345347 * MARK: - Macros (Private)
@@ -438,6 +440,7 @@ uint32_t yyjson_version(void) {
438440#define MSG_ERR_UTF8 "invalid utf-8 encoding in string"
439441#define MSG_ERR_UTF16 "UTF-16 encoding is not supported"
440442#define MSG_ERR_UTF32 "UTF-32 encoding is not supported"
443+ #define MSG_DEPTH "depth limit exceeded"
441444
442445/* U64 constant values */
443446#undef U64_MAX
@@ -5306,6 +5309,7 @@ fail_literal_null: return_err(cur, LITERAL, MSG_CHAR_N);
53065309fail_character : return_err (cur , UNEXPECTED_CHARACTER , MSG_CHAR );
53075310fail_comment : return_err (cur , INVALID_COMMENT , MSG_COMMENT );
53085311fail_garbage : return_err (cur , UNEXPECTED_CONTENT , MSG_GARBAGE );
5312+ fail_depth : return_err (cur , DEPTH , MSG_DEPTH );
53095313
53105314#undef return_err
53115315}
@@ -5366,6 +5370,10 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, u8 *cur, u8 *eof,
53665370 u8 * raw_ptr = raw_end ;
53675371 u8 * * pre = & raw_ptr ; /* previous raw end pointer */
53685372
5373+ #if YYJSON_READER_DEPTH_LIMIT
5374+ u32 container_depth = 0 ; /* current array/object depth */
5375+ #endif
5376+
53695377 dat_len = has_flg (STOP_WHEN_DONE ) ? 256 : (usize )(eof - cur );
53705378 hdr_len = sizeof (yyjson_doc ) / sizeof (yyjson_val );
53715379 hdr_len += (sizeof (yyjson_doc ) % sizeof (yyjson_val )) > 0 ;
@@ -5391,6 +5399,12 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, u8 *cur, u8 *eof,
53915399 }
53925400
53935401arr_begin :
5402+ #if YYJSON_READER_DEPTH_LIMIT
5403+ container_depth ++ ;
5404+ if (unlikely (container_depth >= YYJSON_READER_DEPTH_LIMIT )) {
5405+ goto fail_depth ;
5406+ }
5407+ #endif
53945408 /* save current container */
53955409 ctn -> tag = (((u64 )ctn_len + 1 ) << YYJSON_TAG_BIT ) |
53965410 (ctn -> tag & YYJSON_TAG_MASK );
@@ -5496,6 +5510,9 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, u8 *cur, u8 *eof,
54965510 goto fail_character_arr_end ;
54975511
54985512arr_end :
5513+ #if YYJSON_READER_DEPTH_LIMIT
5514+ container_depth -- ;
5515+ #endif
54995516 /* get parent container */
55005517 ctn_parent = (yyjson_val * )(void * )((u8 * )ctn - ctn -> uni .ofs );
55015518
@@ -5514,6 +5531,12 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, u8 *cur, u8 *eof,
55145531 }
55155532
55165533obj_begin :
5534+ #if YYJSON_READER_DEPTH_LIMIT
5535+ container_depth ++ ;
5536+ if (unlikely (container_depth >= YYJSON_READER_DEPTH_LIMIT )) {
5537+ goto fail_depth ;
5538+ }
5539+ #endif
55175540 /* push container */
55185541 ctn -> tag = (((u64 )ctn_len + 1 ) << YYJSON_TAG_BIT ) |
55195542 (ctn -> tag & YYJSON_TAG_MASK );
@@ -5660,6 +5683,9 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, u8 *cur, u8 *eof,
56605683 goto fail_character_obj_end ;
56615684
56625685obj_end :
5686+ #if YYJSON_READER_DEPTH_LIMIT
5687+ container_depth -- ;
5688+ #endif
56635689 /* pop container */
56645690 ctn_parent = (yyjson_val * )(void * )((u8 * )ctn - ctn -> uni .ofs );
56655691 /* point to the next value */
@@ -5709,6 +5735,7 @@ fail_character_obj_sep: return_err(cur, UNEXPECTED_CHARACTER, MSG_OBJ_SEP);
57095735fail_character_obj_end : return_err (cur , UNEXPECTED_CHARACTER , MSG_OBJ_END );
57105736fail_comment : return_err (cur , INVALID_COMMENT , MSG_COMMENT );
57115737fail_garbage : return_err (cur , UNEXPECTED_CONTENT , MSG_GARBAGE );
5738+ fail_depth : return_err (cur , DEPTH , MSG_DEPTH );
57125739
57135740#undef val_incr
57145741#undef return_err
@@ -5769,6 +5796,9 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, u8 *cur, u8 *eof,
57695796 u8 raw_end [1 ]; /* raw end for null-terminator */
57705797 u8 * raw_ptr = raw_end ;
57715798 u8 * * pre = & raw_ptr ; /* previous raw end pointer */
5799+ #if YYJSON_READER_DEPTH_LIMIT
5800+ u32 container_depth = 0 ; /* current array/object depth */
5801+ #endif
57725802
57735803 dat_len = has_flg (STOP_WHEN_DONE ) ? 256 : (usize )(eof - cur );
57745804 hdr_len = sizeof (yyjson_doc ) / sizeof (yyjson_val );
@@ -5797,6 +5827,13 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, u8 *cur, u8 *eof,
57975827 }
57985828
57995829arr_begin :
5830+ #if YYJSON_READER_DEPTH_LIMIT
5831+ container_depth ++ ;
5832+ if (unlikely (container_depth >= YYJSON_READER_DEPTH_LIMIT )) {
5833+ goto fail_depth ;
5834+ }
5835+ #endif
5836+
58005837 /* save current container */
58015838 ctn -> tag = (((u64 )ctn_len + 1 ) << YYJSON_TAG_BIT ) |
58025839 (ctn -> tag & YYJSON_TAG_MASK );
@@ -5919,6 +5956,9 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, u8 *cur, u8 *eof,
59195956 goto fail_character_arr_end ;
59205957
59215958arr_end :
5959+ #if YYJSON_READER_DEPTH_LIMIT
5960+ container_depth -- ;
5961+ #endif
59225962 /* get parent container */
59235963 ctn_parent = (yyjson_val * )(void * )((u8 * )ctn - ctn -> uni .ofs );
59245964
@@ -5938,6 +5978,13 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, u8 *cur, u8 *eof,
59385978 }
59395979
59405980obj_begin :
5981+ #if YYJSON_READER_DEPTH_LIMIT
5982+ container_depth ++ ;
5983+ if (unlikely (container_depth >= YYJSON_READER_DEPTH_LIMIT )) {
5984+ goto fail_depth ;
5985+ }
5986+ #endif
5987+
59415988 /* push container */
59425989 ctn -> tag = (((u64 )ctn_len + 1 ) << YYJSON_TAG_BIT ) |
59435990 (ctn -> tag & YYJSON_TAG_MASK );
@@ -6104,6 +6151,10 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, u8 *cur, u8 *eof,
61046151 goto fail_character_obj_end ;
61056152
61066153obj_end :
6154+ #if YYJSON_READER_DEPTH_LIMIT
6155+ container_depth -- ;
6156+ #endif
6157+
61076158 /* pop container */
61086159 ctn_parent = (yyjson_val * )(void * )((u8 * )ctn - ctn -> uni .ofs );
61096160 /* point to the next value */
@@ -6154,6 +6205,7 @@ fail_character_obj_sep: return_err(cur, UNEXPECTED_CHARACTER, MSG_OBJ_SEP);
61546205fail_character_obj_end : return_err (cur , UNEXPECTED_CHARACTER , MSG_OBJ_END );
61556206fail_comment : return_err (cur , INVALID_COMMENT , MSG_COMMENT );
61566207fail_garbage : return_err (cur , UNEXPECTED_CONTENT , MSG_GARBAGE );
6208+ fail_depth : return_err (cur , DEPTH , MSG_DEPTH );
61576209
61586210#undef val_incr
61596211#undef return_err
@@ -6612,6 +6664,10 @@ yyjson_doc *yyjson_incr_read(yyjson_incr_state *state, size_t len,
66126664 u8 * * con = NULL ; /* for incremental string parsing */
66136665 u8 saved_end = '\0' ; /* saved end char */
66146666
6667+ #if YYJSON_READER_DEPTH_LIMIT
6668+ u32 container_depth = 0 ; /* current array/object depth */
6669+ #endif
6670+
66156671 /* validate input parameters */
66166672 if (!err ) err = & tmp_err ;
66176673 if (unlikely (!state )) {
@@ -6733,6 +6789,13 @@ yyjson_doc *yyjson_incr_read(yyjson_incr_state *state, size_t len,
67336789 return_err (cur , UNEXPECTED_CHARACTER , msg );
67346790
67356791arr_begin :
6792+ #if YYJSON_READER_DEPTH_LIMIT
6793+ container_depth ++ ;
6794+ if (unlikely (container_depth >= YYJSON_READER_DEPTH_LIMIT )) {
6795+ goto fail_depth ;
6796+ }
6797+ #endif
6798+
67366799 /* save current container */
67376800 ctn -> tag = (((u64 )ctn_len + 1 ) << YYJSON_TAG_BIT ) |
67386801 (ctn -> tag & YYJSON_TAG_MASK );
@@ -6822,6 +6885,9 @@ yyjson_doc *yyjson_incr_read(yyjson_incr_state *state, size_t len,
68226885 goto fail_character_arr_end ;
68236886
68246887arr_end :
6888+ #if YYJSON_READER_DEPTH_LIMIT
6889+ container_depth -- ;
6890+ #endif
68256891 /* get parent container */
68266892 ctn_parent = (yyjson_val * )(void * )((u8 * )ctn - ctn -> uni .ofs );
68276893
@@ -6840,6 +6906,13 @@ yyjson_doc *yyjson_incr_read(yyjson_incr_state *state, size_t len,
68406906 }
68416907
68426908obj_begin :
6909+ #if YYJSON_READER_DEPTH_LIMIT
6910+ container_depth ++ ;
6911+ if (unlikely (container_depth >= YYJSON_READER_DEPTH_LIMIT )) {
6912+ goto fail_depth ;
6913+ }
6914+ #endif
6915+
68436916 /* push container */
68446917 ctn -> tag = (((u64 )ctn_len + 1 ) << YYJSON_TAG_BIT ) |
68456918 (ctn -> tag & YYJSON_TAG_MASK );
@@ -6954,6 +7027,10 @@ yyjson_doc *yyjson_incr_read(yyjson_incr_state *state, size_t len,
69547027 goto fail_character_obj_end ;
69557028
69567029obj_end :
7030+ #if YYJSON_READER_DEPTH_LIMIT
7031+ container_depth -- ;
7032+ #endif
7033+
69577034 /* pop container */
69587035 ctn_parent = (yyjson_val * )(void * )((u8 * )ctn - ctn -> uni .ofs );
69597036 /* point to the next value */
@@ -7020,6 +7097,7 @@ fail_character_obj_key: return_err(cur, UNEXPECTED_CHARACTER, MSG_OBJ_KEY);
70207097fail_character_obj_sep : return_err (cur , UNEXPECTED_CHARACTER , MSG_OBJ_SEP );
70217098fail_character_obj_end : return_err (cur , UNEXPECTED_CHARACTER , MSG_OBJ_END );
70227099fail_garbage : return_err (cur , UNEXPECTED_CONTENT , MSG_GARBAGE );
7100+ fail_depth : return_err (cur , DEPTH , MSG_DEPTH );
70237101
70247102#undef val_incr
70257103#undef return_err
0 commit comments