mirror of
https://github.com/kgabis/parson.git
synced 2025-01-14 06:12:54 +08:00
Handling realloc, strdup and strndup errors.
Also moved void* cast in free to the parson_free macro.
This commit is contained in:
parent
1f7049dd47
commit
ee9be98974
58
parson.c
58
parson.c
@ -32,7 +32,7 @@
|
|||||||
#define sizeof_token(a) (sizeof(a) - 1)
|
#define sizeof_token(a) (sizeof(a) - 1)
|
||||||
|
|
||||||
#define parson_malloc(a) malloc(a)
|
#define parson_malloc(a) malloc(a)
|
||||||
#define parson_free(a) free(a)
|
#define parson_free(a) free((void*)a)
|
||||||
#define parson_realloc(a, b) realloc(a, b)
|
#define parson_realloc(a, b) realloc(a, b)
|
||||||
|
|
||||||
/* Type definitions */
|
/* Type definitions */
|
||||||
@ -102,11 +102,9 @@ static JSON_Value * parse_value(const char **string, size_t nesting);
|
|||||||
static JSON_Object * json_object_init(void) {
|
static JSON_Object * json_object_init(void) {
|
||||||
JSON_Object *new_obj = (JSON_Object*)parson_malloc(sizeof(JSON_Object));
|
JSON_Object *new_obj = (JSON_Object*)parson_malloc(sizeof(JSON_Object));
|
||||||
if (!new_obj) { return NULL; }
|
if (!new_obj) { return NULL; }
|
||||||
new_obj->names = (const char**)parson_malloc(sizeof(char*) *
|
new_obj->names = (const char**)parson_malloc(sizeof(char*) * STARTING_CAPACITY);
|
||||||
STARTING_CAPACITY);
|
|
||||||
if (!new_obj->names) { parson_free(new_obj); return NULL; }
|
if (!new_obj->names) { parson_free(new_obj); return NULL; }
|
||||||
new_obj->values = (JSON_Value**)parson_malloc(sizeof(JSON_Value*) *
|
new_obj->values = (JSON_Value**)parson_malloc(sizeof(JSON_Value*) * STARTING_CAPACITY);
|
||||||
STARTING_CAPACITY);
|
|
||||||
if (!new_obj->values) { parson_free(new_obj->names); parson_free(new_obj); return NULL; }
|
if (!new_obj->values) { parson_free(new_obj->names); parson_free(new_obj); return NULL; }
|
||||||
new_obj->capacity = STARTING_CAPACITY;
|
new_obj->capacity = STARTING_CAPACITY;
|
||||||
new_obj->count = 0;
|
new_obj->count = 0;
|
||||||
@ -115,18 +113,22 @@ static JSON_Object * json_object_init(void) {
|
|||||||
|
|
||||||
static int json_object_add(JSON_Object *object, const char *name, JSON_Value *value) {
|
static int json_object_add(JSON_Object *object, const char *name, JSON_Value *value) {
|
||||||
size_t index;
|
size_t index;
|
||||||
|
void *reallocated_ptr;
|
||||||
if (object->count >= object->capacity) {
|
if (object->count >= object->capacity) {
|
||||||
size_t new_capacity = object->capacity * 2;
|
size_t new_capacity = object->capacity * 2;
|
||||||
if (new_capacity > MAX_CAPACITY) { return 0; }
|
if (new_capacity > MAX_CAPACITY) { return 0; }
|
||||||
object->names = (const char**)parson_realloc((void*)object->names,
|
reallocated_ptr = parson_realloc((void*)object->names, new_capacity * sizeof(char*));
|
||||||
new_capacity * sizeof(char*));
|
if (!reallocated_ptr) { return 0;}
|
||||||
object->values = (JSON_Value**)parson_realloc(object->values,
|
object->names = (const char**)reallocated_ptr;
|
||||||
new_capacity * sizeof(JSON_Value*));
|
reallocated_ptr = parson_realloc(object->values, new_capacity * sizeof(JSON_Value*));
|
||||||
|
if (!reallocated_ptr) { return 0;}
|
||||||
|
object->values = (JSON_Value**)reallocated_ptr;
|
||||||
object->capacity = new_capacity;
|
object->capacity = new_capacity;
|
||||||
}
|
}
|
||||||
if (json_object_get_value(object, name) != NULL) { return 0; }
|
if (json_object_get_value(object, name) != NULL) { return 0; }
|
||||||
index = object->count;
|
index = object->count;
|
||||||
object->names[index] = parson_strdup(name);
|
object->names[index] = parson_strdup(name);
|
||||||
|
if (!object->names[index]) { return 0; }
|
||||||
object->values[index] = value;
|
object->values[index] = value;
|
||||||
object->count++;
|
object->count++;
|
||||||
return 1;
|
return 1;
|
||||||
@ -135,10 +137,10 @@ static int json_object_add(JSON_Object *object, const char *name, JSON_Value *va
|
|||||||
static void json_object_free(JSON_Object *object) {
|
static void json_object_free(JSON_Object *object) {
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < object->count; i++) {
|
for (i = 0; i < object->count; i++) {
|
||||||
parson_free((void*)object->names[i]);
|
parson_free(object->names[i]);
|
||||||
json_value_free(object->values[i]);
|
json_value_free(object->values[i]);
|
||||||
}
|
}
|
||||||
parson_free((void*)object->names);
|
parson_free(object->names);
|
||||||
parson_free(object->values);
|
parson_free(object->values);
|
||||||
parson_free(object);
|
parson_free(object);
|
||||||
}
|
}
|
||||||
@ -147,8 +149,7 @@ static void json_object_free(JSON_Object *object) {
|
|||||||
static JSON_Array * json_array_init(void) {
|
static JSON_Array * json_array_init(void) {
|
||||||
JSON_Array *new_array = (JSON_Array*)parson_malloc(sizeof(JSON_Array));
|
JSON_Array *new_array = (JSON_Array*)parson_malloc(sizeof(JSON_Array));
|
||||||
if (!new_array) { return NULL; }
|
if (!new_array) { return NULL; }
|
||||||
new_array->items = (JSON_Value**)parson_malloc(STARTING_CAPACITY *
|
new_array->items = (JSON_Value**)parson_malloc(STARTING_CAPACITY * sizeof(JSON_Value*));
|
||||||
sizeof(JSON_Value*));
|
|
||||||
if (!new_array->items) { parson_free(new_array); return NULL; }
|
if (!new_array->items) { parson_free(new_array); return NULL; }
|
||||||
new_array->capacity = STARTING_CAPACITY;
|
new_array->capacity = STARTING_CAPACITY;
|
||||||
new_array->count = 0;
|
new_array->count = 0;
|
||||||
@ -156,11 +157,13 @@ static JSON_Array * json_array_init(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int json_array_add(JSON_Array *array, JSON_Value *value) {
|
static int json_array_add(JSON_Array *array, JSON_Value *value) {
|
||||||
|
void *reallocated_ptr;
|
||||||
if (array->count >= array->capacity) {
|
if (array->count >= array->capacity) {
|
||||||
size_t new_capacity = array->capacity * 2;
|
size_t new_capacity = array->capacity * 2;
|
||||||
if (new_capacity > MAX_CAPACITY) { return 0; }
|
if (new_capacity > MAX_CAPACITY) { return 0; }
|
||||||
array->items = (JSON_Value**)parson_realloc(array->items,
|
reallocated_ptr = parson_realloc(array->items, new_capacity * sizeof(JSON_Value*));
|
||||||
new_capacity * sizeof(JSON_Value*));
|
if (!reallocated_ptr) { return 0; }
|
||||||
|
array->items = (JSON_Value**)reallocated_ptr;
|
||||||
array->capacity = new_capacity;
|
array->capacity = new_capacity;
|
||||||
}
|
}
|
||||||
array->items[array->count] = value;
|
array->items[array->count] = value;
|
||||||
@ -253,6 +256,7 @@ static char * copy_and_remove_whitespaces(const char *string) {
|
|||||||
char *output_string_ptr = output_string;
|
char *output_string_ptr = output_string;
|
||||||
const char *string_ptr = string;
|
const char *string_ptr = string;
|
||||||
const char *skipped_string = NULL;
|
const char *skipped_string = NULL;
|
||||||
|
void *reallocated_ptr;
|
||||||
char current_char;
|
char current_char;
|
||||||
if (!output_string) { return NULL; }
|
if (!output_string) { return NULL; }
|
||||||
while (*string_ptr) {
|
while (*string_ptr) {
|
||||||
@ -276,7 +280,9 @@ static char * copy_and_remove_whitespaces(const char *string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*output_string_ptr = '\0';
|
*output_string_ptr = '\0';
|
||||||
output_string = (char*)parson_realloc(output_string, strlen(output_string) + 1);
|
reallocated_ptr = parson_realloc(output_string, strlen(output_string) + 1);
|
||||||
|
if (!reallocated_ptr) { parson_free(output_string); return NULL; }
|
||||||
|
output_string = (char*)reallocated_ptr;
|
||||||
return output_string;
|
return output_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,6 +307,7 @@ static const char * parse_escaped_characters(const char *string) {
|
|||||||
const char *string_ptr = string;
|
const char *string_ptr = string;
|
||||||
char current_char;
|
char current_char;
|
||||||
unsigned int utf_val;
|
unsigned int utf_val;
|
||||||
|
void *reallocated_ptr;
|
||||||
if (!output_string) { return NULL; }
|
if (!output_string) { return NULL; }
|
||||||
while (*string_ptr) {
|
while (*string_ptr) {
|
||||||
current_char = *string_ptr;
|
current_char = *string_ptr;
|
||||||
@ -346,7 +353,9 @@ static const char * parse_escaped_characters(const char *string) {
|
|||||||
string_ptr++;
|
string_ptr++;
|
||||||
}
|
}
|
||||||
*output_string_ptr = '\0';
|
*output_string_ptr = '\0';
|
||||||
output_string = (char*)parson_realloc(output_string, strlen(output_string) + 1);
|
reallocated_ptr = parson_realloc(output_string, strlen(output_string) + 1);
|
||||||
|
if (!reallocated_ptr) { parson_free(output_string); return NULL; }
|
||||||
|
output_string = (char*)reallocated_ptr;
|
||||||
return output_string;
|
return output_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,6 +368,7 @@ static const char * get_string(const char **string) {
|
|||||||
const char *after_closing_quote_ptr = skip_string(*string);
|
const char *after_closing_quote_ptr = skip_string(*string);
|
||||||
if (!after_closing_quote_ptr) { return NULL; }
|
if (!after_closing_quote_ptr) { return NULL; }
|
||||||
quote_contents = parson_strndup(*string + 1, after_closing_quote_ptr - *string - 2);
|
quote_contents = parson_strndup(*string + 1, after_closing_quote_ptr - *string - 2);
|
||||||
|
if (!quote_contents) { return NULL; }
|
||||||
*string = after_closing_quote_ptr;
|
*string = after_closing_quote_ptr;
|
||||||
parsed_string = parse_escaped_characters(quote_contents);
|
parsed_string = parse_escaped_characters(quote_contents);
|
||||||
parson_free(quote_contents);
|
parson_free(quote_contents);
|
||||||
@ -411,17 +421,17 @@ static JSON_Value * parse_object_value(const char **string, size_t nesting) {
|
|||||||
(*string)++;
|
(*string)++;
|
||||||
new_value = parse_value(string, nesting);
|
new_value = parse_value(string, nesting);
|
||||||
if (!new_value) {
|
if (!new_value) {
|
||||||
parson_free((void*)new_key);
|
parson_free(new_key);
|
||||||
json_value_free(output_value);
|
json_value_free(output_value);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(!json_object_add(json_value_get_object(output_value), new_key, new_value)) {
|
if(!json_object_add(json_value_get_object(output_value), new_key, new_value)) {
|
||||||
parson_free((void*)new_key);
|
parson_free(new_key);
|
||||||
parson_free(new_value);
|
parson_free(new_value);
|
||||||
json_value_free(output_value);
|
json_value_free(output_value);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
parson_free((void*)new_key);
|
parson_free(new_key);
|
||||||
if (**string != ',') { break; }
|
if (**string != ',') { break; }
|
||||||
(*string)++;
|
(*string)++;
|
||||||
}
|
}
|
||||||
@ -486,6 +496,7 @@ static JSON_Value * parse_number_value(const char **string) {
|
|||||||
double number = strtod(*string, &end);
|
double number = strtod(*string, &end);
|
||||||
JSON_Value *output_value;
|
JSON_Value *output_value;
|
||||||
number_string = parson_strndup(*string, end - *string);
|
number_string = parson_strndup(*string, end - *string);
|
||||||
|
if (!number_string) { return NULL; }
|
||||||
if (is_decimal(number_string, end - *string)) {
|
if (is_decimal(number_string, end - *string)) {
|
||||||
*string = end;
|
*string = end;
|
||||||
output_value = json_value_init_number(number);
|
output_value = json_value_init_number(number);
|
||||||
@ -533,7 +544,7 @@ JSON_Value * json_parse_string(const char *string) {
|
|||||||
if (*json_string == '{' || *json_string == '[') {
|
if (*json_string == '{' || *json_string == '[') {
|
||||||
output_value = parse_value((const char**)&json_string_ptr, 0);
|
output_value = parse_value((const char**)&json_string_ptr, 0);
|
||||||
}
|
}
|
||||||
parson_free((void*)json_string);
|
parson_free(json_string);
|
||||||
return output_value;
|
return output_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,9 +583,10 @@ JSON_Value * json_object_dotget_value(const JSON_Object *object, const char *nam
|
|||||||
JSON_Value *output_value;
|
JSON_Value *output_value;
|
||||||
if (!dot_position) { return json_object_get_value(object, name); }
|
if (!dot_position) { return json_object_get_value(object, name); }
|
||||||
object_name = parson_strndup(name, dot_position - name);
|
object_name = parson_strndup(name, dot_position - name);
|
||||||
|
if (!object_name) { return NULL; }
|
||||||
output_value = json_object_dotget_value(json_object_get_object(object, object_name),
|
output_value = json_object_dotget_value(json_object_get_object(object, object_name),
|
||||||
dot_position + 1);
|
dot_position + 1);
|
||||||
parson_free((void*)object_name);
|
parson_free(object_name);
|
||||||
return output_value;
|
return output_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,7 +671,7 @@ void json_value_free(JSON_Value *value) {
|
|||||||
json_object_free(value->value.object);
|
json_object_free(value->value.object);
|
||||||
break;
|
break;
|
||||||
case JSONString:
|
case JSONString:
|
||||||
if (value->value.string) { parson_free((void*)value->value.string); }
|
if (value->value.string) { parson_free(value->value.string); }
|
||||||
break;
|
break;
|
||||||
case JSONArray:
|
case JSONArray:
|
||||||
json_array_free(value->value.array);
|
json_array_free(value->value.array);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user