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.
 
 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
 ----
 
 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
 .. 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)
 
 .. 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;
 
 {
     json_object_t *object;
 
+    if(!key || !value)
+        return -1;
+
     if(!json_is_object(json))
     {
         json_decref(value);
     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;
 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);
     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;
 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);
     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_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)
        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)
 {
     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);
         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_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");
 
     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, 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");
 
     if(json_array_size(array) != 2)
         fail("wrong array size");
 
@@ -85,16 +91,26 @@ int main()
             fail("got wrong value");
     }
 
             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");
 
     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");
 
     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);
     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, "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");
     iter = json_object_iter(object);
     if(!iter)
         fail("unable to get iterator");
@@ -105,11 +111,19 @@ int main()
         fail("unable to set value");
 
 
         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");
 
     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);
     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);
 
         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");
     value = json_integer(123);
     if(!value)
         fail("json_integer failed");