From: Petri Lehtinen Date: Mon, 21 Dec 2009 12:00:40 +0000 (+0200) Subject: Add _nocheck functions X-Git-Tag: v1.2~15 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=jansson.git;a=commitdiff_plain;h=dd2fe1ebe80fa9a95265fbcd20b6ffdfdc30d469 Add _nocheck functions 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. --- diff --git a/doc/apiref.rst b/doc/apiref.rst index fd2a7c9..1ca7c2b 100644 --- a/doc/apiref.rst +++ b/doc/apiref.rst @@ -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 diff --git a/src/jansson.h b/src/jansson.h index 59e3eb5..25906dd 100644 --- a/src/jansson.h +++ b/src/jansson.h @@ -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); diff --git a/src/jansson_private.h b/src/jansson_private.h index 317f05a..3e9bb7f 100644 --- a/src/jansson_private.h +++ b/src/jansson_private.h @@ -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 diff --git a/src/value.c b/src/value.c index ccf9f06..0ab8232 100644 --- a/src/value.c +++ b/src/value.c @@ -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); diff --git a/test/suites/api/test_object.c b/test/suites/api/test_object.c index 57650e8..7e9ada8 100644 --- a/test/suites/api/test_object.c +++ b/test/suites/api/test_object.c @@ -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; } diff --git a/test/suites/api/test_simple.c b/test/suites/api/test_simple.c index 9d7691e..0284879 100644 --- a/test/suites/api/test_simple.c +++ b/test/suites/api/test_simple.c @@ -73,6 +73,33 @@ int main() if(value) fail("json_string() 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)