Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

update json_object_new_string_len, json_escape_str (internal). Writer…

… handles \x00 correctly

Added parse_null test. This does not change anything with how the parser handles \u0000 or null characters

This commit is addapted from one by Adomas Paltanavičius <adomas@leanholding.com>



git-svn-id: http://svn.metaparadigm.com/svn/json-c/trunk@63 327403b1-1117-474d-bef2-5cb71233fd97
  • Loading branch information...
commit ac601b5b5f9bc76200a37f39a47a62d414708aa2 1 parent a503ee8
@jehiah authored
View
7 Makefile.am
@@ -32,7 +32,7 @@ libjson_la_SOURCES = \
linkhash.c \
printbuf.c
-check_PROGRAMS = test1 test2 test4 test_parse_int64
+check_PROGRAMS = test1 test2 test4 test_parse_int64 test_null
test1_SOURCES = test1.c
test1_LDADD = $(lib_LTLIBRARIES)
@@ -46,7 +46,10 @@ test4_LDADD = $(lib_LTLIBRARIES)
test_parse_int64_SOURCES = test_parse_int64.c
test_parse_int64_LDADD = $(lib_LTLIBRARIES)
-TESTS = test1.test test2.test test4.test parse_int64.test
+test_null_SOURCES = test_null.c
+test_null_LDADD = $(lib_LTLIBRARIES)
+
+TESTS = test1.test test2.test test4.test parse_int64.test test_null.test
EXTRA_DIST += $(TESTS)
testsubdir=testSubDir
TESTS_ENVIRONMENT = top_builddir=$(top_builddir)
View
41 json_object.c
@@ -83,15 +83,13 @@ static void json_object_fini(void) {
/* string escaping */
-static int json_escape_str(struct printbuf *pb, char *str)
+static int json_escape_str(struct printbuf *pb, char *str, int len)
{
int pos = 0, start_offset = 0;
unsigned char c;
- do {
+ while (len--) {
c = str[pos];
switch(c) {
- case '\0':
- break;
case '\b':
case '\n':
case '\r':
@@ -120,7 +118,7 @@ static int json_escape_str(struct printbuf *pb, char *str)
start_offset = ++pos;
} else pos++;
}
- } while(c);
+ }
if(pos - start_offset > 0)
printbuf_memappend(pb, str + start_offset, pos - start_offset);
return 0;
@@ -218,7 +216,7 @@ static int json_object_object_to_json_string(struct json_object* jso,
json_object_object_foreachC(jso, iter) {
if(i) sprintbuf(pb, ",");
sprintbuf(pb, " \"");
- json_escape_str(pb, iter.key);
+ json_escape_str(pb, iter.key, strlen(iter.key));
sprintbuf(pb, "\": ");
if(iter.val == NULL) sprintbuf(pb, "null");
else iter.val->_to_json_string(iter.val, pb);
@@ -309,7 +307,7 @@ boolean json_object_get_boolean(struct json_object *jso)
case json_type_double:
return (jso->o.c_double != 0);
case json_type_string:
- return (strlen(jso->o.c_string) != 0);
+ return (jso->o.c_string.len != 0);
default:
return FALSE;
}
@@ -346,7 +344,7 @@ int32_t json_object_get_int(struct json_object *jso)
* Parse strings into 64-bit numbers, then use the
* 64-to-32-bit number handling below.
*/
- if (json_parse_int64(jso->o.c_string, &cint64) != 0)
+ if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
return 0; /* whoops, it didn't work. */
o_type = json_type_int;
}
@@ -391,7 +389,7 @@ int64_t json_object_get_int64(struct json_object *jso)
case json_type_boolean:
return jso->o.c_boolean;
case json_type_string:
- if (json_parse_int64(jso->o.c_string, &cint) == 0) return cint;
+ if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
default:
return 0;
}
@@ -428,7 +426,7 @@ double json_object_get_double(struct json_object *jso)
case json_type_boolean:
return jso->o.c_boolean;
case json_type_string:
- if(sscanf(jso->o.c_string, "%lf", &cdouble) == 1) return cdouble;
+ if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
default:
return 0.0;
}
@@ -441,14 +439,14 @@ static int json_object_string_to_json_string(struct json_object* jso,
struct printbuf *pb)
{
sprintbuf(pb, "\"");
- json_escape_str(pb, jso->o.c_string);
+ json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
sprintbuf(pb, "\"");
return 0;
}
static void json_object_string_delete(struct json_object* jso)
{
- free(jso->o.c_string);
+ free(jso->o.c_string.str);
json_object_generic_delete(jso);
}
@@ -458,7 +456,8 @@ struct json_object* json_object_new_string(const char *s)
if(!jso) return NULL;
jso->_delete = &json_object_string_delete;
jso->_to_json_string = &json_object_string_to_json_string;
- jso->o.c_string = strdup(s);
+ jso->o.c_string.str = strdup(s);
+ jso->o.c_string.len = strlen(s);
return jso;
}
@@ -468,7 +467,9 @@ struct json_object* json_object_new_string_len(const char *s, int len)
if(!jso) return NULL;
jso->_delete = &json_object_string_delete;
jso->_to_json_string = &json_object_string_to_json_string;
- jso->o.c_string = strndup(s, len);
+ jso->o.c_string.str = malloc(len);
+ memcpy(jso->o.c_string.str, (void *)s, len);
+ jso->o.c_string.len = len;
return jso;
}
@@ -477,12 +478,22 @@ const char* json_object_get_string(struct json_object *jso)
if(!jso) return NULL;
switch(jso->o_type) {
case json_type_string:
- return jso->o.c_string;
+ return jso->o.c_string.str;
default:
return json_object_to_json_string(jso);
}
}
+int json_object_get_string_len(struct json_object *jso) {
+ if(!jso) return 0;
+ switch(jso->o_type) {
+ case json_type_string:
+ return jso->o.c_string.len;
+ default:
+ return 0;
+ }
+}
+
/* json_object_array */
View
10 json_object.h
@@ -337,6 +337,16 @@ extern struct json_object* json_object_new_string_len(const char *s, int len);
*/
extern const char* json_object_get_string(struct json_object *obj);
+/** Get the string length of a json_object
+ *
+ * If the passed object is not of type json_type_string then zero
+ * will be returned.
+ *
+ * @param obj the json_object instance
+ * @returns int
+ */
+extern int json_object_get_string_len(struct json_object *obj);
+
#ifdef __cplusplus
}
#endif
View
5 json_object_private.h
@@ -33,7 +33,10 @@ struct json_object
int64_t c_int64;
struct lh_table *c_object;
struct array_list *c_array;
- char *c_string;
+ struct {
+ char *str;
+ int len;
+ } c_string;
} o;
};
View
35 test_null.c
@@ -0,0 +1,35 @@
+/*
+* Tests if binary strings are supported.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "config.h"
+
+#include "json_inttypes.h"
+#include "json_object.h"
+
+int main() {
+ // this test has a space after the null character. check that it's still included
+ const char *input = " \0 ";
+ const char *expected = "\" \\u0000 \"";
+ struct json_object *string = json_object_new_string_len(input, 3);
+ const char *json = json_object_to_json_string(string);
+
+ int strings_match = !strcmp( expected, json);
+ int retval = 0;
+ if (strings_match) {
+ printf("JSON write result is correct: %s\n", json);
+ printf("PASS\n");
+ } else {
+ printf("JSON write result doesn't match expected string\n");
+ printf("expected string: ");
+ printf("%s\n", expected);
+ printf("parsed string: ");
+ printf("%s\n", json);
+ printf("FAIL\n");
+ retval=1;
+ }
+ json_object_put(string);
+ return retval;
+}
View
2  test_null.expected
@@ -0,0 +1,2 @@
+JSON write result is correct: " \u0000 "
+PASS
View
12 test_null.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Common definitions
+if test -z "$srcdir"; then
+ srcdir="${0%/*}"
+ test "$srcdir" = "$0" && srcdir=.
+ test -z "$srcdir" && srcdir=.
+fi
+. "$srcdir/test-defs.sh"
+
+run_output_test test_null
+exit $?
Please sign in to comment.
Something went wrong with that request. Please try again.