Skip to content

Commit 58a77b9

Browse files
committed
harden JSON parser error handling and bounds checks
1 parent 1c8a3c4 commit 58a77b9

3 files changed

Lines changed: 31 additions & 11 deletions

File tree

src/json/centijson_dom.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,14 @@ json_dom_process(JSON_TYPE type, const unsigned char* data, size_t data_size, vo
266266
* append their json_values. */
267267
if(dom_parser->path_size >= dom_parser->path_alloc) {
268268
JSON_VALUE** new_path;
269-
size_t new_path_alloc = dom_parser->path_alloc * 2;
269+
size_t new_path_alloc;
270270

271-
if(new_path_alloc == 0)
271+
if(dom_parser->path_alloc == 0)
272272
new_path_alloc = 32;
273+
else if(dom_parser->path_alloc > SIZE_MAX / 2 / sizeof(JSON_VALUE*))
274+
return JSON_ERR_OUTOFMEMORY;
275+
else
276+
new_path_alloc = dom_parser->path_alloc * 2;
273277
new_path = (JSON_VALUE**) realloc((void *)dom_parser->path, new_path_alloc * sizeof(JSON_VALUE*));
274278
if(new_path == NULL)
275279
return JSON_ERR_OUTOFMEMORY;
@@ -617,8 +621,14 @@ json_dom_dump_helper(
617621
keys_size = json_value_dict_keys_ordered(node, keys, n);
618622
else
619623
keys_size = json_value_dict_keys_sorted(node, keys, n);
620-
if (keys_size != n)
624+
if (keys_size != n) {
625+
#ifdef WOLFSENTRY
626+
json_free(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), (void *)keys);
627+
#else
628+
free((void *)keys);
629+
#endif
621630
return JSON_ERR_INTERNAL;
631+
}
622632

623633
for(i = 0; i < n; i++) {
624634
JSON_VALUE* json_value;

src/json/centijson_sax.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -857,10 +857,11 @@ json_feed(JSON_PARSER* parser, const unsigned char* input, size_t size)
857857
{
858858
/* Update parser->pos to point to the exact place. */
859859
while(parser->pos.offset < parser->config.max_total_len) {
860+
ch = input[off];
861+
off++;
860862
parser->pos.offset++;
861863
parser->pos.column_number++;
862-
off++;
863-
json_handle_new_line(parser, input[off]);
864+
json_handle_new_line(parser, ch);
864865
}
865866

866867
json_raise(parser, JSON_ERR_MAXTOTALLEN);
@@ -891,10 +892,15 @@ json_feed(JSON_PARSER* parser, const unsigned char* input, size_t size)
891892

892893
if(parser->nesting_level >= parser->nesting_stack_size) {
893894
unsigned char* new_nesting_stack;
894-
size_t new_nesting_stack_size = parser->nesting_stack_size * 2;
895+
size_t new_nesting_stack_size;
895896

896-
if(new_nesting_stack_size == 0)
897+
if(parser->nesting_stack_size == 0)
897898
new_nesting_stack_size = 32;
899+
else if(parser->nesting_stack_size > SIZE_MAX / 2) {
900+
json_raise(parser, JSON_ERR_OUTOFMEMORY);
901+
break;
902+
} else
903+
new_nesting_stack_size = parser->nesting_stack_size * 2;
898904
new_nesting_stack = (unsigned char *)realloc(parser->nesting_stack, new_nesting_stack_size);
899905
if(new_nesting_stack == NULL) {
900906
json_raise(parser, JSON_ERR_OUTOFMEMORY);

src/json/centijson_value.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,15 +1794,19 @@ json_value_dict_clean(
17941794
WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator),
17951795
#endif
17961796
&node->key);
1797-
if (ret < 0)
1797+
if (ret < 0) {
1798+
free((void *)stack);
17981799
return ret;
1800+
}
17991801
ret = json_value_fini(
18001802
#ifdef WOLFSENTRY
18011803
WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator),
18021804
#endif
18031805
&node->json_value);
1804-
if (ret < 0)
1806+
if (ret < 0) {
1807+
free((void *)stack);
18051808
return ret;
1809+
}
18061810
free(node);
18071811

18081812
stack_size += json_value_dict_leftmost_path(stack + stack_size, right);
@@ -1928,6 +1932,8 @@ json_value_clone(WOLFSENTRY_CONTEXT_ARGS_IN_EX(struct wolfsentry_allocator *allo
19281932
break;
19291933
}
19301934
ret = json_value_clone(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), &src_dict_node->json_value, dest_node);
1935+
if (ret < 0)
1936+
break;
19311937
src_dict_node = src_dict_node->order_next;
19321938
}
19331939
} else {
@@ -1954,8 +1960,6 @@ json_value_clone(WOLFSENTRY_CONTEXT_ARGS_IN_EX(struct wolfsentry_allocator *allo
19541960
}
19551961

19561962
free((void *)stack);
1957-
1958-
break;
19591963
}
19601964
if (ret < 0) {
19611965
int ret2 = json_value_fini(WOLFSENTRY_CONTEXT_ARGS_OUT_EX(allocator), clone);

0 commit comments

Comments
 (0)