Add _nocheck functions
authorPetri Lehtinen <petri@digip.org>
Mon, 21 Dec 2009 12:00:40 +0000 (14:00 +0200)
committerPetri Lehtinen <petri@digip.org>
Wed, 23 Dec 2009 20:28:24 +0000 (22:28 +0200)
Added functions are:

* json_string_nocheck()
* json_string_set_nocheck()
* json_object_set_nocheck()
* json_object_set_new_nocheck()

These functions don't check that their string argument is valid UTF-8,
but assume that the user has already performed the check.

doc/apiref.rst
src/jansson.h
src/jansson_private.h
src/value.c
test/suites/api/test_object.c
test/suites/api/test_simple.c

index fd2a7c9..1ca7c2b 100644 (file)
@@ -229,6 +229,16 @@ String
    Returns a new JSON string, or *NULL* on error. *value* must be a
    valid UTF-8 encoded Unicode string.
 
+.. cfunction:: json_t *json_string_nocheck(const char *value)
+
+   .. refcounting:: new
+
+   Like :cfunc:`json_string`, but doesn't check that *value* is valid
+   UTF-8. Use this function only if you are certain that this really
+   is the case (e.g. you have already checked it by other means).
+
+   .. versionadded:: 1.2
+
 .. cfunction:: const char *json_string_value(const json_t *string)
 
    Returns the associated value of *string* as a null terminated UTF-8
@@ -242,6 +252,15 @@ String
 
    .. versionadded:: 1.1
 
+.. cfunction:: int json_string_set_nocheck(const json_t *string, const char *value)
+
+   Like :cfunc:`json_string_set`, but doesn't check that *value* is
+   valid UTF-8. Use this function only if you are certain that this
+   really is the case (e.g. you have already checked it by other
+   means).
+
+   .. versionadded:: 1.2
+
 
 Number
 ======
@@ -420,6 +439,15 @@ Unicode string and the value is any JSON value.
    already is a value for *key*, it is replaced by the new value.
    Returns 0 on success and -1 on error.
 
+.. cfunction:: int json_object_set_nocheck(json_t *object, const char *key, json_t *value)
+
+   Like :cfunc:`json_object_set`, but doesn't check that *key* is
+   valid UTF-8. Use this function only if you are certain that this
+   really is the case (e.g. you have already checked it by other
+   means).
+
+   .. versionadded:: 1.2
+
 .. cfunction:: int json_object_set_new(json_t *object, const char *key, json_t *value)
 
    Like :cfunc:`json_object_set()` but steals the reference to
@@ -428,6 +456,15 @@ Unicode string and the value is any JSON value.
 
    .. versionadded:: 1.1
 
+.. cfunction:: int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value)
+
+   Like :cfunc:`json_object_set_new`, but doesn't check that *key* is
+   valid UTF-8. Use this function only if you are certain that this
+   really is the case (e.g. you have already checked it by other
+   means).
+
+   .. versionadded:: 1.2
+
 .. cfunction:: int json_object_del(json_t *object, const char *key)
 
    Delete *key* from *object* if it exists. Returns 0 on success, or
index 59e3eb5..25906dd 100644 (file)
@@ -49,6 +49,7 @@ typedef struct {
 json_t *json_object(void);
 json_t *json_array(void);
 json_t *json_string(const char *value);
+json_t *json_string_nocheck(const char *value);
 json_t *json_integer(int value);
 json_t *json_real(double value);
 json_t *json_true(void);
@@ -77,6 +78,7 @@ static inline void json_decref(json_t *json)
 unsigned int json_object_size(const json_t *object);
 json_t *json_object_get(const json_t *object, const char *key);
 int json_object_set_new(json_t *object, const char *key, json_t *value);
+int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value);
 int json_object_del(json_t *object, const char *key);
 int json_object_clear(json_t *object);
 int json_object_update(json_t *object, json_t *other);
@@ -91,6 +93,12 @@ int json_object_set(json_t *object, const char *key, json_t *value)
     return json_object_set_new(object, key, json_incref(value));
 }
 
+static inline
+int json_object_set_nocheck(json_t *object, const char *key, json_t *value)
+{
+    return json_object_set_new_nocheck(object, key, json_incref(value));
+}
+
 unsigned int json_array_size(const json_t *array);
 json_t *json_array_get(const json_t *array, unsigned int index);
 int json_array_set_new(json_t *array, unsigned int index, json_t *value);
@@ -124,6 +132,7 @@ double json_real_value(const json_t *real);
 double json_number_value(const json_t *json);
 
 int json_string_set(json_t *string, const char *value);
+int json_string_set_nocheck(json_t *string, const char *value);
 int json_integer_set(json_t *integer, int value);
 int json_real_set(json_t *real, double value);
 
index 317f05a..3e9bb7f 100644 (file)
@@ -49,7 +49,4 @@ typedef struct {
 #define json_to_real(json_)   container_of(json_, json_real_t, json)
 #define json_to_integer(json_) container_of(json_, json_integer_t, json)
 
-int json_object_set_nocheck(json_t *json, const char *key, json_t *value);
-json_t *json_string_nocheck(const char *value);
-
 #endif
index ccf9f06..0ab8232 100644 (file)
@@ -120,11 +120,6 @@ int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
     return 0;
 }
 
-int json_object_set_nocheck(json_t *json, const char *key, json_t *value)
-{
-    return json_object_set_new_nocheck(json, key, json_incref(value));
-}
-
 int json_object_set_new(json_t *json, const char *key, json_t *value)
 {
     if(!key || !utf8_check_string(key, -1))
@@ -508,14 +503,11 @@ const char *json_string_value(const json_t *json)
     return json_to_string(json)->value;
 }
 
-int json_string_set(json_t *json, const char *value)
+int json_string_set_nocheck(json_t *json, const char *value)
 {
     char *dup;
     json_string_t *string;
 
-    if(!json_is_string(json) || !value || !utf8_check_string(value, -1))
-        return -1;
-
     dup = strdup(value);
     if(!dup)
         return -1;
@@ -527,6 +519,14 @@ int json_string_set(json_t *json, const char *value)
     return 0;
 }
 
+int json_string_set(json_t *json, const char *value)
+{
+    if(!value || !utf8_check_string(value, -1))
+        return -1;
+
+    return json_string_set_nocheck(json, value);
+}
+
 static void json_delete_string(json_string_t *string)
 {
     free(string->value);
index 57650e8..7e9ada8 100644 (file)
@@ -167,6 +167,44 @@ static void test_circular()
     json_decref(object1);
 }
 
+static void test_set_nocheck()
+{
+    json_t *object, *string;
+
+    object = json_object();
+    string = json_string("bar");
+
+    if(!object)
+        fail("unable to create object");
+    if(!string)
+        fail("unable to create string");
+
+    if(json_object_set_nocheck(object, "foo", string))
+        fail("json_object_set_nocheck failed");
+    if(json_object_get(object, "foo") != string)
+        fail("json_object_get after json_object_set_nocheck failed");
+
+    /* invalid UTF-8 in key */
+    if(json_object_set_nocheck(object, "a\xefz", string))
+        fail("json_object_set_nocheck failed for invalid UTF-8");
+    if(json_object_get(object, "a\xefz") != string)
+        fail("json_object_get after json_object_set_nocheck failed");
+
+    if(json_object_set_new_nocheck(object, "bax", json_integer(123)))
+        fail("json_object_set_new_nocheck failed");
+    if(json_integer_value(json_object_get(object, "bax")) != 123)
+        fail("json_object_get after json_object_set_new_nocheck failed");
+
+    /* invalid UTF-8 in key */
+    if(json_object_set_new_nocheck(object, "asdf\xfe", json_integer(321)))
+        fail("json_object_set_new_nocheck failed for invalid UTF-8");
+    if(json_integer_value(json_object_get(object, "asdf\xfe")) != 321)
+        fail("json_object_get after json_object_set_new_nocheck failed");
+
+    json_decref(string);
+    json_decref(object);
+}
+
 static void test_misc()
 {
     json_t *object, *string, *other_string, *value;
@@ -293,6 +331,7 @@ int main()
     test_clear();
     test_update();
     test_circular();
+    test_set_nocheck();
 
     return 0;
 }
index 9d7691e..0284879 100644 (file)
@@ -73,6 +73,33 @@ int main()
     if(value)
         fail("json_string(<invalid utf-8>) failed");
 
+    value = json_string_nocheck("foo");
+    if(!value)
+        fail("json_string_nocheck failed");
+    if(strcmp(json_string_value(value), "foo"))
+        fail("invalid string value");
+
+    if(json_string_set_nocheck(value, "bar"))
+        fail("json_string_set_nocheck failed");
+    if(strcmp(json_string_value(value), "bar"))
+        fail("invalid string value");
+
+    json_decref(value);
+
+    /* invalid UTF-8 */
+    value = json_string_nocheck("qu\xff");
+    if(!value)
+        fail("json_string_nocheck failed");
+    if(strcmp(json_string_value(value), "qu\xff"))
+        fail("invalid string value");
+
+    if(json_string_set_nocheck(value, "\xfd\xfe\xff"))
+        fail("json_string_set_nocheck failed");
+    if(strcmp(json_string_value(value), "\xfd\xfe\xff"))
+        fail("invalid string value");
+
+    json_decref(value);
+
 
     value = json_integer(123);
     if(!value)