[PATCH] lib: fwts_json: free objects where necessary to plug heap leaks
Colin King
colin.king at canonical.com
Wed Apr 28 23:26:33 UTC 2021
From: Colin Ian King <colin.king at canonical.com>
There are quite a few places where token handling and object
handling error paths need to free any allocated token or json
objects. Fix these.
Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
src/lib/src/fwts_json.c | 60 +++++++++++++++++++++++++++++++++--------
1 file changed, 49 insertions(+), 11 deletions(-)
diff --git a/src/lib/src/fwts_json.c b/src/lib/src/fwts_json.c
index 3182ea74..15f2a556 100644
--- a/src/lib/src/fwts_json.c
+++ b/src/lib/src/fwts_json.c
@@ -261,6 +261,18 @@ int json_get_keyword(json_file *jfile, json_token *token)
return token_error;
}
+/*
+ * json_free_token()
+ * free any heap allocated members in token when required
+ */
+void json_free_token(json_token *token)
+{
+ if (token->type == token_string) {
+ free(token->u.str);
+ token->u.str = NULL;
+ }
+}
+
/*
* json_get_token()
* read next input character(s) and return a matching token
@@ -363,10 +375,14 @@ json_object *json_parse_array(json_file *jfile)
obj = json_parse_object(jfile);
if (!obj) {
json_parse_error_where(jfile);
- free(array_obj);
+ json_object_put(array_obj);
+ return NULL;
+ }
+ if (json_object_array_add(array_obj, obj) < 0) {
+ json_object_put(array_obj);
+ json_object_put(obj);
return NULL;
}
- json_object_array_add(array_obj, obj);
switch (json_get_token(jfile, &token)) {
case token_rbracket:
@@ -376,9 +392,11 @@ json_object *json_parse_array(json_file *jfile)
default:
if (json_unget_token(jfile, &token) != 0) {
fprintf(stderr, "json_parser: failed to unget a token\n");
- free(array_obj);
+ json_object_put(array_obj);
+ json_free_token(&token);
return NULL;
}
+ json_free_token(&token);
break;
}
}
@@ -393,10 +411,10 @@ json_object *json_parse_object(json_file *jfile)
{
json_token token;
json_object *obj, *val_obj;
- char *key = NULL;
if (json_get_token(jfile, &token) != token_lbrace) {
fprintf(stderr, "json_parser: expecting '{', got %s instead\n", json_token_string(&token));
+ json_free_token(&token);
return NULL;
}
@@ -405,59 +423,76 @@ json_object *json_parse_object(json_file *jfile)
goto err_nomem;
for (;;) {
+ char *key = NULL;
+
switch (json_get_token(jfile, &token)) {
case token_rbrace:
+ json_free_token(&token);
return obj;
case token_string:
- key = token.u.str;
+ key = strdup(token.u.str);
if (!key)
goto err_nomem;
- token.u.str = NULL;
+ json_free_token(&token);
break;
default:
fprintf(stderr, "json_parser: expecting } or key literal string, got %s instead\n", json_token_string(&token));
goto err_free;
}
+
+ json_free_token(&token);
if (json_get_token(jfile, &token) != token_colon) {
fprintf(stderr, "json_parser: expecting ':', got %s instead\n", json_token_string(&token));
+ free(key);
goto err_free;
}
switch (json_get_token(jfile, &token)) {
case token_string:
val_obj = json_object_new_string(token.u.str);
- if (!val_obj)
+ if (!val_obj) {
+ free(key);
goto err_nomem;
+ }
json_object_object_add(obj, key, val_obj);
- free(key);
break;
case token_int:
val_obj = json_object_new_int(token.u.intval);
- if (!val_obj)
+ if (!val_obj) {
+ free(key);
goto err_nomem;
+ }
json_object_object_add(obj, key, val_obj);
- free(key);
break;
case token_lbracket:
val_obj = json_parse_array(jfile);
- if (!val_obj)
+ if (!val_obj) {
+ free(key);
goto err_nomem;
+ }
json_object_object_add(obj, key, val_obj);
break;
case token_lbrace:
fprintf(stderr, "json_parser: nested objects not supported\n");
+ free(key);
goto err_free;
case token_true:
case token_false:
case token_null:
fprintf(stderr, "json_parser: tokens %s not supported\n", json_token_string(&token));
+ free(key);
goto err_free;
default:
fprintf(stderr, "json_parser: unexpected token %s\n", json_token_string(&token));
}
+ free(key);
+
+ json_free_token(&token);
switch (json_get_token(jfile, &token)) {
case token_comma:
+ json_free_token(&token);
continue;
case token_rbrace:
+ json_free_token(&token);
return obj;
default:
fprintf(stderr, "json_parser: expected , or }, got %s instead\n", json_token_string(&token));
@@ -470,6 +505,7 @@ err_nomem:
json_parse_error_where(jfile);
err_free:
free(obj);
+ json_free_token(&token);
return NULL;
}
@@ -880,6 +916,7 @@ static char *json_object_to_json_string_indent(json_object *obj, int indent)
return NULL;
}
str = str_append(str, obj_str);
+ free(obj_str);
if (!str)
return NULL;
}
@@ -919,6 +956,7 @@ static char *json_object_to_json_string_indent(json_object *obj, int indent)
return NULL;
}
str = str_append(str, obj_str);
+ free(obj_str);
if (!str)
return NULL;
}
--
2.30.2
More information about the fwts-devel
mailing list