]> granicus.if.org Git - json-c/commitdiff
Make it safe to delete keys while iterating with the json_object_object_foreach macro.
authorEric Haszlakiewicz <erh+git@nimenees.com>
Sun, 21 Oct 2012 01:26:37 +0000 (20:26 -0500)
committerEric Haszlakiewicz <erh+git@nimenees.com>
Sun, 21 Oct 2012 01:26:37 +0000 (20:26 -0500)
json_object.h
tests/testReplaceExisting.c
tests/testReplaceExisting.expected

index 3f0ec6a3d4b64f2424c7024ef22d071e759f34a7..262111262e6d33cd0ad5fa0100e0c5b931f7c436 100644 (file)
@@ -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.
  *
- * 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 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) \
        char *key; \
        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) { \
                        key = (char*)entry->k; \
                        val = (struct json_object*)entry->v; \
+                       entry_next = entry->next; \
                } ; entry; }); \
-               entry = entry->next )
+               entry = entry_next )
 
 #else /* ANSI C or MSC */
 
@@ -317,12 +319,14 @@ extern void json_object_object_del(struct json_object* obj, const char *key);
        char *key;\
        struct json_object *val; \
        struct lh_entry *entry; \
+       struct lh_entry *entry_next = NULL; \
        for(entry = json_object_get_object(obj)->head; \
                (entry ? ( \
                        key = (char*)entry->k, \
                        val = (struct json_object*)entry->v, \
+                       entry_next = entry->next, \
                        entry) : 0); \
-               entry = entry->next)
+               entry = entry_next)
 
 #endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) */
 
index 8c8c4b20aa0cb9b98884ce97e9d7cb87d56393a4..69a71452c5d86aa3bd7d5709176e3347eb1f1be4 100644 (file)
@@ -16,9 +16,29 @@ int main(int argc, char **argv)
        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, "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"));
-       const char *original_key = NULL;
+
+       printf("==== delete-in-loop test starting ====\n");
+
        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)
        {
                printf("Key at index %d is [%s]\n", orig_count, key);
index 4d1c509e311ee5086b70f314da101ab0b6903ca0..b1d4461b04163f37fcfbd88dac827477083f550a 100644 (file)
@@ -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 1 is [foo2]
 replacing value for key [foo2]