Skip to content

Commit

Permalink
update json_object_new_string_len, json_escape_str (internal). Writer…
Browse files Browse the repository at this point in the history
… 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
jehiah committed Jan 14, 2011
1 parent a503ee8 commit ac601b5
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 18 deletions.
7 changes: 5 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
41 changes: 26 additions & 15 deletions json_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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':
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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 */

Expand Down
10 changes: 10 additions & 0 deletions json_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion json_object_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down
35 changes: 35 additions & 0 deletions test_null.c
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 2 additions & 0 deletions test_null.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
JSON write result is correct: " \u0000 "
PASS
12 changes: 12 additions & 0 deletions test_null.test
Original file line number Diff line number Diff line change
@@ -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 $?

0 comments on commit ac601b5

Please sign in to comment.