Better argument validation
authorPetri Lehtinen <petri@digip.org>
Sun, 6 Sep 2009 19:24:55 +0000 (22:24 +0300)
committerPetri Lehtinen <petri@digip.org>
Sun, 6 Sep 2009 19:24:55 +0000 (22:24 +0300)
All pointer arguments are now tested for NULL. json_string() now also
tests that strdup() succeeds. This is to ensure that no NULL values
end up in data structures.

Also desribe the different sources of errors in documentation.

doc/apiref.rst
src/value.c
test/testprogs/test_array.c
test/testprogs/test_object.c
test/testprogs/test_simple.c

index db9b5a4..ea38343 100644 (file)
@@ -41,6 +41,12 @@ Objects of :ctype:`json_t` are always used through a pointer. There
 are APIs for querying the type, manipulating the reference count, and
 for constructing and manipulating values of different types.
 
+Unless noted otherwise, all API functions return an error value if an
+error occurs. Depending on the function's signature, the error value
+is either *NULL* or -1. Invalid arguments or invalid input are
+apparent sources for errors. Memory allocation and I/O operations may
+also cause errors.
+
 
 Type
 ----
@@ -80,8 +86,8 @@ functions:
 .. cfunction:: int json_typeof(const json_t *json)
 
    Return the type of the JSON value (a :ctype:`json_type` cast to
-   :ctype:`int`). This function is actually implemented as a macro for
-   speed.
+   :ctype:`int`). *json* MUST NOT be *NULL*. This function is actually
+   implemented as a macro for speed.
 
 .. cfunction:: json_is_object(const json_t *json)
                json_is_array(const json_t *json)
index d83d575..c84bfd3 100644 (file)
@@ -122,6 +122,9 @@ int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
 {
     json_object_t *object;
 
+    if(!key || !value)
+        return -1;
+
     if(!json_is_object(json))
     {
         json_decref(value);
@@ -255,6 +258,10 @@ json_t *json_array_get(const json_t *json, unsigned int index)
 int json_array_set_new(json_t *json, unsigned int index, json_t *value)
 {
     json_array_t *array;
+
+    if(!value)
+        return -1;
+
     if(!json_is_array(json))
     {
         json_decref(value);
@@ -277,6 +284,10 @@ int json_array_set_new(json_t *json, unsigned int index, json_t *value)
 int json_array_append_new(json_t *json, json_t *value)
 {
     json_array_t *array;
+
+    if(!value)
+        return -1;
+
     if(!json_is_array(json))
     {
         json_decref(value);
@@ -305,18 +316,28 @@ int json_array_append_new(json_t *json, json_t *value)
 
 json_t *json_string_nocheck(const char *value)
 {
-    json_string_t *string = malloc(sizeof(json_string_t));
+    json_string_t *string;
+
+    if(!value)
+        return NULL;
+
+    string = malloc(sizeof(json_string_t));
     if(!string)
        return NULL;
     json_init(&string->json, JSON_STRING);
 
     string->value = strdup(value);
+    if(!string->value) {
+        free(string);
+        return NULL;
+    }
+
     return &string->json;
 }
 
 json_t *json_string(const char *value)
 {
-    if(!utf8_check_string(value, -1))
+    if(!value || !utf8_check_string(value, -1))
         return NULL;
 
     return json_string_nocheck(value);
index 97a8513..b597afb 100644 (file)
@@ -27,6 +27,9 @@ int main()
     if(json_array_size(array) != 0)
         fail("empty array has nonzero size");
 
+    if(!json_array_append(array, NULL))
+        fail("able to append NULL");
+
     if(json_array_append(array, five))
         fail("unable to append");
 
@@ -54,6 +57,9 @@ int main()
     if(json_array_set(array, 0, seven))
         fail("unable to set value");
 
+    if(!json_array_set(array, 0, NULL))
+        fail("able to set NULL");
+
     if(json_array_size(array) != 2)
         fail("wrong array size");
 
@@ -85,16 +91,26 @@ int main()
             fail("got wrong value");
     }
 
-    json_array_set_new(array, 15, json_integer(123));
+    if(json_array_set_new(array, 15, json_integer(123)))
+        fail("unable to set new value");
+
     value = json_array_get(array, 15);
     if(!json_is_integer(value) || json_integer_value(value) != 123)
       fail("json_array_set_new works incorrectly");
 
-    json_array_append_new(array, json_integer(321));
+    if(!json_array_set_new(array, 15, NULL))
+        fail("able to set_new NULL value");
+
+    if(json_array_append_new(array, json_integer(321)))
+        fail("unable to append new value");
+
     value = json_array_get(array, json_array_size(array) - 1);
     if(!json_is_integer(value) || json_integer_value(value) != 321)
       fail("json_array_append_new works incorrectly");
 
+    if(!json_array_append_new(array, NULL))
+        fail("able to append_new NULL value");
+
     json_decref(five);
     json_decref(seven);
     json_decref(array);
index f9839c7..540109e 100644 (file)
@@ -29,6 +29,12 @@ int main()
     if(json_object_set(object, "a", string))
         fail("unable to set value");
 
+    if(!json_object_set(object, NULL, string))
+        fail("able to set NULL key");
+
+    if(!json_object_set(object, "a", NULL))
+        fail("able to set NULL value");
+
     iter = json_object_iter(object);
     if(!iter)
         fail("unable to get iterator");
@@ -105,11 +111,19 @@ int main()
         fail("unable to set value");
 
 
-    json_object_set_new(object, "foo", json_integer(123));
+    if(json_object_set_new(object, "foo", json_integer(123)))
+        fail("unable to set new value");
+
     value = json_object_get(object, "foo");
     if(!json_is_integer(value) || json_integer_value(value) != 123)
       fail("json_object_set_new works incorrectly");
 
+    if(!json_object_set_new(object, NULL, json_integer(432)))
+        fail("able to set_new NULL key");
+
+    if(!json_object_set_new(object, "foo", NULL))
+        fail("able to set_new NULL value");
+
     json_decref(string);
     json_decref(other_string);
     json_decref(object);
index 86f841b..4491ed2 100644 (file)
@@ -58,6 +58,10 @@ int main()
         fail("invalid string value");
     json_decref(value);
 
+    value = json_string(NULL);
+    if(value)
+        fail("json_string(NULL) failed");
+
     value = json_integer(123);
     if(!value)
         fail("json_integer failed");