From a14a3a680c862321a88b8fb9fc9da922e4dcda93 Mon Sep 17 00:00:00 2001 From: Eric Hawicz Date: Wed, 26 Jul 2023 18:15:07 -0400 Subject: [PATCH] Fix an uninitialized memory access in json_pointer. Add comments describing when the fields of the internal struct json_pointer_get_result are valid. --- json_patch.c | 6 +++--- json_pointer.c | 17 ++++++++--------- json_pointer_private.h | 9 +++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/json_patch.c b/json_patch.c index 97d9dd8..b48eed8 100644 --- a/json_patch.c +++ b/json_patch.c @@ -49,9 +49,9 @@ static int json_patch_apply_test(struct json_object **res, static int __json_patch_apply_remove(struct json_pointer_get_result *jpres) { if (json_object_is_type(jpres->parent, json_type_array)) { - return json_object_array_del_idx(jpres->parent, jpres->id.index, 1); - } else if (jpres->parent && jpres->id.key) { - json_object_object_del(jpres->parent, jpres->id.key); + return json_object_array_del_idx(jpres->parent, jpres->index_in_parent, 1); + } else if (jpres->parent && jpres->key_in_parent) { + json_object_object_del(jpres->parent, jpres->key_in_parent); return 0; } else { return json_object_put(jpres->obj); diff --git a/json_pointer.c b/json_pointer.c index e6e5f91..89e9e21 100644 --- a/json_pointer.c +++ b/json_pointer.c @@ -190,9 +190,9 @@ static int json_pointer_result_get_recursive(struct json_object *obj, char *path res->parent = parent_obj; res->obj = obj; if (json_object_is_type(res->parent, json_type_array)) - res->id.index = idx; + res->index_in_parent = idx; else - res->id.key = path; + res->key_in_parent = path; } return 0; @@ -228,11 +228,10 @@ int json_pointer_get_internal(struct json_object *obj, const char *path, if (path[0] == '\0') { - if (res) { - res->parent = NULL; - res->obj = obj; - } - res->id.key = NULL; + res->parent = NULL; + res->obj = obj; + res->key_in_parent = NULL; + res->index_in_parent = -1; return 0; } @@ -244,8 +243,8 @@ int json_pointer_get_internal(struct json_object *obj, const char *path, } rc = json_pointer_result_get_recursive(obj, path_copy, res); /* re-map the path string to the const-path string */ - if (rc == 0 && res->id.key && !json_object_is_type(res->parent, json_type_array)) - res->id.key = path + (res->id.key - path_copy); + if (rc == 0 && json_object_is_type(res->parent, json_type_object) && res->key_in_parent) + res->key_in_parent = path + (res->key_in_parent - path_copy); free(path_copy); return rc; diff --git a/json_pointer_private.h b/json_pointer_private.h index 40ec76d..537cabd 100644 --- a/json_pointer_private.h +++ b/json_pointer_private.h @@ -19,10 +19,11 @@ extern "C" { struct json_pointer_get_result { struct json_object *parent; struct json_object *obj; - union { - const char *key; - uint32_t index; - } id; + // The key of the found object; only valid when parent is json_type_object + // Caution: re-uses tail end of the `path` argument to json_pointer_get_internal + const char *key_in_parent; + // the index of the found object; only valid when parent is json_type_array + uint32_t index_in_parent; }; int json_pointer_get_internal(struct json_object *obj, const char *path,