parse_object: goto fail error handling

Makes the control flow easier to reason about and fixes a few potential
memory leaks.
This commit is contained in:
Max Bruckner 2017-02-06 18:39:56 +01:00
parent 99cd9af7d5
commit 021b174ee1

26
cJSON.c
View File

@ -1370,7 +1370,7 @@ static const unsigned char *parse_object(cJSON *item, const unsigned char *value
{ {
/* not an object! */ /* not an object! */
*ep = value; *ep = value;
return NULL; goto fail;
} }
item->type = cJSON_Object; item->type = cJSON_Object;
@ -1385,13 +1385,13 @@ static const unsigned char *parse_object(cJSON *item, const unsigned char *value
item->child = child; item->child = child;
if (!item->child) if (!item->child)
{ {
return NULL; goto fail;
} }
/* parse first key */ /* parse first key */
value = skip(parse_string(child, skip(value), ep)); value = skip(parse_string(child, skip(value), ep));
if (!value) if (!value)
{ {
return NULL; goto fail;
} }
/* use string as key, not value */ /* use string as key, not value */
child->string = child->valuestring; child->string = child->valuestring;
@ -1401,13 +1401,13 @@ static const unsigned char *parse_object(cJSON *item, const unsigned char *value
{ {
/* invalid object. */ /* invalid object. */
*ep = value; *ep = value;
return NULL; goto fail;
} }
/* skip any spacing, get the value. */ /* skip any spacing, get the value. */
value = skip(parse_value(child, skip(value + 1), ep)); value = skip(parse_value(child, skip(value + 1), ep));
if (!value) if (!value)
{ {
return NULL; goto fail;
} }
while (*value == ',') while (*value == ',')
@ -1416,7 +1416,7 @@ static const unsigned char *parse_object(cJSON *item, const unsigned char *value
if (!(new_item = cJSON_New_Item())) if (!(new_item = cJSON_New_Item()))
{ {
/* memory fail */ /* memory fail */
return NULL; goto fail;
} }
/* add to linked list */ /* add to linked list */
child->next = new_item; child->next = new_item;
@ -1426,7 +1426,7 @@ static const unsigned char *parse_object(cJSON *item, const unsigned char *value
value = skip(parse_string(child, skip(value + 1), ep)); value = skip(parse_string(child, skip(value + 1), ep));
if (!value) if (!value)
{ {
return NULL; goto fail;
} }
/* use string as key, not value */ /* use string as key, not value */
@ -1437,13 +1437,13 @@ static const unsigned char *parse_object(cJSON *item, const unsigned char *value
{ {
/* invalid object. */ /* invalid object. */
*ep = value; *ep = value;
return NULL; goto fail;
} }
/* skip any spacing, get the value. */ /* skip any spacing, get the value. */
value = skip(parse_value(child, skip(value + 1), ep)); value = skip(parse_value(child, skip(value + 1), ep));
if (!value) if (!value)
{ {
return NULL; goto fail;
} }
} }
/* end of object */ /* end of object */
@ -1454,6 +1454,14 @@ static const unsigned char *parse_object(cJSON *item, const unsigned char *value
/* malformed */ /* malformed */
*ep = value; *ep = value;
fail:
if (item->child != NULL)
{
cJSON_Delete(child);
item->child = NULL;
}
return NULL; return NULL;
} }