mirror of
https://github.com/json-c/json-c.git
synced 2026-03-20 13:39:06 +08:00
Merge pull request #219 from rouault/low_heap_robustness_fixes
Fix various potential null ptr deref and int32 overflows
This commit is contained in:
16
arraylist.c
16
arraylist.c
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
@@ -62,10 +64,17 @@ static int array_list_expand_internal(struct array_list *arr, int max)
|
||||
int new_size;
|
||||
|
||||
if(max < arr->size) return 0;
|
||||
new_size = arr->size << 1;
|
||||
if (new_size < max)
|
||||
/* Avoid undefined behaviour on int32 overflow */
|
||||
if( arr->size >= INT_MAX / 2 )
|
||||
new_size = max;
|
||||
if(!(t = realloc(arr->array, new_size*sizeof(void*)))) return -1;
|
||||
else
|
||||
{
|
||||
new_size = arr->size << 1;
|
||||
if (new_size < max)
|
||||
new_size = max;
|
||||
}
|
||||
if((size_t)new_size > (~((size_t)0)) / sizeof(void*)) return -1;
|
||||
if(!(t = realloc(arr->array, ((size_t)new_size)*sizeof(void*)))) return -1;
|
||||
arr->array = (void**)t;
|
||||
(void)memset(arr->array + arr->size, 0, (new_size-arr->size)*sizeof(void*));
|
||||
arr->size = new_size;
|
||||
@@ -75,6 +84,7 @@ static int array_list_expand_internal(struct array_list *arr, int max)
|
||||
int
|
||||
array_list_put_idx(struct array_list *arr, int idx, void *data)
|
||||
{
|
||||
if( idx < 0 || idx > INT_MAX - 1 ) return -1;
|
||||
if(array_list_expand_internal(arr, idx+1)) return -1;
|
||||
if(arr->array[idx]) arr->free_fn(arr->array[idx]);
|
||||
arr->array[idx] = data;
|
||||
|
||||
@@ -934,6 +934,11 @@ struct json_object* json_object_new_array(void)
|
||||
jso->_delete = &json_object_array_delete;
|
||||
jso->_to_json_string = &json_object_array_to_json_string;
|
||||
jso->o.c_array = array_list_new(&json_object_array_entry_free);
|
||||
if(jso->o.c_array == NULL)
|
||||
{
|
||||
free(jso);
|
||||
return NULL;
|
||||
}
|
||||
return jso;
|
||||
}
|
||||
|
||||
|
||||
@@ -286,11 +286,15 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
state = json_tokener_state_eatws;
|
||||
saved_state = json_tokener_state_object_field_start;
|
||||
current = json_object_new_object();
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
break;
|
||||
case '[':
|
||||
state = json_tokener_state_eatws;
|
||||
saved_state = json_tokener_state_array;
|
||||
current = json_object_new_array();
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
break;
|
||||
case 'I':
|
||||
case 'i':
|
||||
@@ -376,6 +380,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
if (tok->st_pos == json_inf_str_len)
|
||||
{
|
||||
current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
@@ -413,6 +419,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
if (tok->st_pos == json_nan_str_len)
|
||||
{
|
||||
current = json_object_new_double(NAN);
|
||||
if (current == NULL)
|
||||
goto out;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
@@ -486,6 +494,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
if(c == tok->quote_char) {
|
||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
||||
current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
break;
|
||||
@@ -646,6 +656,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
) {
|
||||
if(tok->st_pos == json_true_str_len) {
|
||||
current = json_object_new_boolean(1);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
@@ -655,6 +667,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
|| (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
|
||||
if(tok->st_pos == json_false_str_len) {
|
||||
current = json_object_new_boolean(0);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
@@ -737,10 +751,14 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
goto out;
|
||||
}
|
||||
current = json_object_new_int64(num64);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
}
|
||||
else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0)
|
||||
{
|
||||
current = json_object_new_double_s(numd, tok->pb->buf);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
} else {
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
@@ -775,7 +793,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
break;
|
||||
|
||||
case json_tokener_state_array_add:
|
||||
json_object_array_add(current, obj);
|
||||
if( json_object_array_add(current, obj) != 0 )
|
||||
goto out;
|
||||
saved_state = json_tokener_state_array_sep;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
|
||||
Reference in New Issue
Block a user