Make it safe to delete keys while iterating with the json_object_object_foreach macro.
This commit is contained in:
@@ -290,9 +290,10 @@ extern void json_object_object_del(struct json_object* obj, const char *key);
|
|||||||
/**
|
/**
|
||||||
* Iterate through all keys and values of an object.
|
* Iterate through all keys and values of an object.
|
||||||
*
|
*
|
||||||
* Adding or deleting keys to the object while iterating is NOT allowed.
|
* Adding keys to the object while iterating is NOT allowed.
|
||||||
*
|
*
|
||||||
* Replacing an existing key with a new value IS allowed.
|
* Deleting an existing key, or replacing an existing key with a
|
||||||
|
* new value IS allowed.
|
||||||
*
|
*
|
||||||
* @param obj the json_object instance
|
* @param obj the json_object instance
|
||||||
* @param key the local name for the char* key variable defined in the body
|
* @param key the local name for the char* key variable defined in the body
|
||||||
@@ -304,12 +305,13 @@ extern void json_object_object_del(struct json_object* obj, const char *key);
|
|||||||
# define json_object_object_foreach(obj,key,val) \
|
# define json_object_object_foreach(obj,key,val) \
|
||||||
char *key; \
|
char *key; \
|
||||||
struct json_object *val; \
|
struct json_object *val; \
|
||||||
for(struct lh_entry *entry = json_object_get_object(obj)->head; \
|
for(struct lh_entry *entry = json_object_get_object(obj)->head, *entry_next = NULL; \
|
||||||
({ if(entry) { \
|
({ if(entry) { \
|
||||||
key = (char*)entry->k; \
|
key = (char*)entry->k; \
|
||||||
val = (struct json_object*)entry->v; \
|
val = (struct json_object*)entry->v; \
|
||||||
|
entry_next = entry->next; \
|
||||||
} ; entry; }); \
|
} ; entry; }); \
|
||||||
entry = entry->next )
|
entry = entry_next )
|
||||||
|
|
||||||
#else /* ANSI C or MSC */
|
#else /* ANSI C or MSC */
|
||||||
|
|
||||||
@@ -317,12 +319,14 @@ extern void json_object_object_del(struct json_object* obj, const char *key);
|
|||||||
char *key;\
|
char *key;\
|
||||||
struct json_object *val; \
|
struct json_object *val; \
|
||||||
struct lh_entry *entry; \
|
struct lh_entry *entry; \
|
||||||
|
struct lh_entry *entry_next = NULL; \
|
||||||
for(entry = json_object_get_object(obj)->head; \
|
for(entry = json_object_get_object(obj)->head; \
|
||||||
(entry ? ( \
|
(entry ? ( \
|
||||||
key = (char*)entry->k, \
|
key = (char*)entry->k, \
|
||||||
val = (struct json_object*)entry->v, \
|
val = (struct json_object*)entry->v, \
|
||||||
|
entry_next = entry->next, \
|
||||||
entry) : 0); \
|
entry) : 0); \
|
||||||
entry = entry->next)
|
entry = entry_next)
|
||||||
|
|
||||||
#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) */
|
#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) */
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,29 @@ int main(int argc, char **argv)
|
|||||||
json_object *my_object = json_object_new_object();
|
json_object *my_object = json_object_new_object();
|
||||||
json_object_object_add(my_object, "foo1", json_object_new_string("bar1"));
|
json_object_object_add(my_object, "foo1", json_object_new_string("bar1"));
|
||||||
json_object_object_add(my_object, "foo2", json_object_new_string("bar2"));
|
json_object_object_add(my_object, "foo2", json_object_new_string("bar2"));
|
||||||
|
json_object_object_add(my_object, "deleteme", json_object_new_string("bar2"));
|
||||||
json_object_object_add(my_object, "foo3", json_object_new_string("bar3"));
|
json_object_object_add(my_object, "foo3", json_object_new_string("bar3"));
|
||||||
const char *original_key = NULL;
|
|
||||||
|
printf("==== delete-in-loop test starting ====\n");
|
||||||
|
|
||||||
int orig_count = 0;
|
int orig_count = 0;
|
||||||
|
json_object_object_foreach(my_object, key0, val0)
|
||||||
|
{
|
||||||
|
printf("Key at index %d is [%s]", orig_count, key0);
|
||||||
|
if (strcmp(key0, "deleteme") == 0)
|
||||||
|
{
|
||||||
|
json_object_object_del(my_object, key0);
|
||||||
|
printf(" (deleted)\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf(" (kept)\n");
|
||||||
|
orig_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("==== replace-value first loop starting ====\n");
|
||||||
|
|
||||||
|
const char *original_key = NULL;
|
||||||
|
orig_count = 0;
|
||||||
json_object_object_foreach(my_object, key, val)
|
json_object_object_foreach(my_object, key, val)
|
||||||
{
|
{
|
||||||
printf("Key at index %d is [%s]\n", orig_count, key);
|
printf("Key at index %d is [%s]\n", orig_count, key);
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
==== delete-in-loop test starting ====
|
||||||
|
Key at index 0 is [foo1] (kept)
|
||||||
|
Key at index 1 is [foo2] (kept)
|
||||||
|
Key at index 2 is [deleteme] (deleted)
|
||||||
|
Key at index 3 is [foo3] (kept)
|
||||||
|
==== replace-value first loop starting ====
|
||||||
Key at index 0 is [foo1]
|
Key at index 0 is [foo1]
|
||||||
Key at index 1 is [foo2]
|
Key at index 1 is [foo2]
|
||||||
replacing value for key [foo2]
|
replacing value for key [foo2]
|
||||||
|
|||||||
Reference in New Issue
Block a user