diff options
author | Ole André Vadla Ravnås <oleavr@gmail.com> | 2020-08-24 17:00:50 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2020-08-24 17:16:26 +0100 |
commit | 73b4f5d3e25d0ecfafd390a880365ffa858f0e73 (patch) | |
tree | 83121668db475255e4bb8ef582f3bda83bb1cd3f /json-glib/json-node.c | |
parent | a697f050bac783d4f1dadfaf4d7407e003a94bef (diff) | |
download | json-glib-deep-copy.tar.gz |
Fix copy behavior for complex typesdeep-copy
The parent of the reffed children were previously left pointing to the
original node. In the best-case scenario this would lead to inconsistent
state when walking down a tree and then walking back up again. In the
worst-case scenario this would happen when the original node had a
shorter life-time than the copy, resulting in use-after-free.
A typical scenario where this went wrong was with json_from_string(),
which would copy the root node, let go of the last reference to the root
node, and then return the copy. The copy would then have dangling
`parent` pointers. This probably went unnoticed for most use-cases, but
would go terribly wrong if someone used a JsonReader and navigated back
up the tree by e.g. calling end_member().
Fixes: #20
Fixes: #32
Diffstat (limited to 'json-glib/json-node.c')
-rw-r--r-- | json-glib/json-node.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/json-glib/json-node.c b/json-glib/json-node.c index a6898d9..fc12d1f 100644 --- a/json-glib/json-node.c +++ b/json-glib/json-node.c @@ -398,9 +398,8 @@ json_node_new (JsonNodeType type) * json_node_copy: * @node: a #JsonNode * - * Copies @node. If the node contains complex data types, their reference - * counts are increased, regardless of whether the node is mutable or - * immutable. + * Copies @node. If the node contains complex data types, those will also + * be copied. * * The copy will be immutable if, and only if, @node is immutable. However, * there should be no need to copy an immutable node. @@ -430,11 +429,11 @@ json_node_copy (JsonNode *node) switch (copy->type) { case JSON_NODE_OBJECT: - copy->data.object = json_node_dup_object (node); + copy->data.object = json_object_copy (node->data.object, copy); break; case JSON_NODE_ARRAY: - copy->data.array = json_node_dup_array (node); + copy->data.array = json_array_copy (node->data.array, copy); break; case JSON_NODE_VALUE: |