Skip to content

Commit ac601b5

Browse files
committed
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
1 parent a503ee8 commit ac601b5

File tree

7 files changed

+94
-18
lines changed

7 files changed

+94
-18
lines changed

Makefile.am

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ libjson_la_SOURCES = \
3232
linkhash.c \
3333
printbuf.c
3434

35-
check_PROGRAMS = test1 test2 test4 test_parse_int64
35+
check_PROGRAMS = test1 test2 test4 test_parse_int64 test_null
3636

3737
test1_SOURCES = test1.c
3838
test1_LDADD = $(lib_LTLIBRARIES)
@@ -46,7 +46,10 @@ test4_LDADD = $(lib_LTLIBRARIES)
4646
test_parse_int64_SOURCES = test_parse_int64.c
4747
test_parse_int64_LDADD = $(lib_LTLIBRARIES)
4848

49-
TESTS = test1.test test2.test test4.test parse_int64.test
49+
test_null_SOURCES = test_null.c
50+
test_null_LDADD = $(lib_LTLIBRARIES)
51+
52+
TESTS = test1.test test2.test test4.test parse_int64.test test_null.test
5053
EXTRA_DIST += $(TESTS)
5154
testsubdir=testSubDir
5255
TESTS_ENVIRONMENT = top_builddir=$(top_builddir)

json_object.c

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,13 @@ static void json_object_fini(void) {
8383

8484
/* string escaping */
8585

86-
static int json_escape_str(struct printbuf *pb, char *str)
86+
static int json_escape_str(struct printbuf *pb, char *str, int len)
8787
{
8888
int pos = 0, start_offset = 0;
8989
unsigned char c;
90-
do {
90+
while (len--) {
9191
c = str[pos];
9292
switch(c) {
93-
case '\0':
94-
break;
9593
case '\b':
9694
case '\n':
9795
case '\r':
@@ -120,7 +118,7 @@ static int json_escape_str(struct printbuf *pb, char *str)
120118
start_offset = ++pos;
121119
} else pos++;
122120
}
123-
} while(c);
121+
}
124122
if(pos - start_offset > 0)
125123
printbuf_memappend(pb, str + start_offset, pos - start_offset);
126124
return 0;
@@ -218,7 +216,7 @@ static int json_object_object_to_json_string(struct json_object* jso,
218216
json_object_object_foreachC(jso, iter) {
219217
if(i) sprintbuf(pb, ",");
220218
sprintbuf(pb, " \"");
221-
json_escape_str(pb, iter.key);
219+
json_escape_str(pb, iter.key, strlen(iter.key));
222220
sprintbuf(pb, "\": ");
223221
if(iter.val == NULL) sprintbuf(pb, "null");
224222
else iter.val->_to_json_string(iter.val, pb);
@@ -309,7 +307,7 @@ boolean json_object_get_boolean(struct json_object *jso)
309307
case json_type_double:
310308
return (jso->o.c_double != 0);
311309
case json_type_string:
312-
return (strlen(jso->o.c_string) != 0);
310+
return (jso->o.c_string.len != 0);
313311
default:
314312
return FALSE;
315313
}
@@ -346,7 +344,7 @@ int32_t json_object_get_int(struct json_object *jso)
346344
* Parse strings into 64-bit numbers, then use the
347345
* 64-to-32-bit number handling below.
348346
*/
349-
if (json_parse_int64(jso->o.c_string, &cint64) != 0)
347+
if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
350348
return 0; /* whoops, it didn't work. */
351349
o_type = json_type_int;
352350
}
@@ -391,7 +389,7 @@ int64_t json_object_get_int64(struct json_object *jso)
391389
case json_type_boolean:
392390
return jso->o.c_boolean;
393391
case json_type_string:
394-
if (json_parse_int64(jso->o.c_string, &cint) == 0) return cint;
392+
if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
395393
default:
396394
return 0;
397395
}
@@ -428,7 +426,7 @@ double json_object_get_double(struct json_object *jso)
428426
case json_type_boolean:
429427
return jso->o.c_boolean;
430428
case json_type_string:
431-
if(sscanf(jso->o.c_string, "%lf", &cdouble) == 1) return cdouble;
429+
if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
432430
default:
433431
return 0.0;
434432
}
@@ -441,14 +439,14 @@ static int json_object_string_to_json_string(struct json_object* jso,
441439
struct printbuf *pb)
442440
{
443441
sprintbuf(pb, "\"");
444-
json_escape_str(pb, jso->o.c_string);
442+
json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
445443
sprintbuf(pb, "\"");
446444
return 0;
447445
}
448446

449447
static void json_object_string_delete(struct json_object* jso)
450448
{
451-
free(jso->o.c_string);
449+
free(jso->o.c_string.str);
452450
json_object_generic_delete(jso);
453451
}
454452

@@ -458,7 +456,8 @@ struct json_object* json_object_new_string(const char *s)
458456
if(!jso) return NULL;
459457
jso->_delete = &json_object_string_delete;
460458
jso->_to_json_string = &json_object_string_to_json_string;
461-
jso->o.c_string = strdup(s);
459+
jso->o.c_string.str = strdup(s);
460+
jso->o.c_string.len = strlen(s);
462461
return jso;
463462
}
464463

@@ -468,7 +467,9 @@ struct json_object* json_object_new_string_len(const char *s, int len)
468467
if(!jso) return NULL;
469468
jso->_delete = &json_object_string_delete;
470469
jso->_to_json_string = &json_object_string_to_json_string;
471-
jso->o.c_string = strndup(s, len);
470+
jso->o.c_string.str = malloc(len);
471+
memcpy(jso->o.c_string.str, (void *)s, len);
472+
jso->o.c_string.len = len;
472473
return jso;
473474
}
474475

@@ -477,12 +478,22 @@ const char* json_object_get_string(struct json_object *jso)
477478
if(!jso) return NULL;
478479
switch(jso->o_type) {
479480
case json_type_string:
480-
return jso->o.c_string;
481+
return jso->o.c_string.str;
481482
default:
482483
return json_object_to_json_string(jso);
483484
}
484485
}
485486

487+
int json_object_get_string_len(struct json_object *jso) {
488+
if(!jso) return 0;
489+
switch(jso->o_type) {
490+
case json_type_string:
491+
return jso->o.c_string.len;
492+
default:
493+
return 0;
494+
}
495+
}
496+
486497

487498
/* json_object_array */
488499

json_object.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,16 @@ extern struct json_object* json_object_new_string_len(const char *s, int len);
337337
*/
338338
extern const char* json_object_get_string(struct json_object *obj);
339339

340+
/** Get the string length of a json_object
341+
*
342+
* If the passed object is not of type json_type_string then zero
343+
* will be returned.
344+
*
345+
* @param obj the json_object instance
346+
* @returns int
347+
*/
348+
extern int json_object_get_string_len(struct json_object *obj);
349+
340350
#ifdef __cplusplus
341351
}
342352
#endif

json_object_private.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ struct json_object
3333
int64_t c_int64;
3434
struct lh_table *c_object;
3535
struct array_list *c_array;
36-
char *c_string;
36+
struct {
37+
char *str;
38+
int len;
39+
} c_string;
3740
} o;
3841
};
3942

test_null.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Tests if binary strings are supported.
3+
*/
4+
5+
#include <stdio.h>
6+
#include <string.h>
7+
#include "config.h"
8+
9+
#include "json_inttypes.h"
10+
#include "json_object.h"
11+
12+
int main() {
13+
// this test has a space after the null character. check that it's still included
14+
const char *input = " \0 ";
15+
const char *expected = "\" \\u0000 \"";
16+
struct json_object *string = json_object_new_string_len(input, 3);
17+
const char *json = json_object_to_json_string(string);
18+
19+
int strings_match = !strcmp( expected, json);
20+
int retval = 0;
21+
if (strings_match) {
22+
printf("JSON write result is correct: %s\n", json);
23+
printf("PASS\n");
24+
} else {
25+
printf("JSON write result doesn't match expected string\n");
26+
printf("expected string: ");
27+
printf("%s\n", expected);
28+
printf("parsed string: ");
29+
printf("%s\n", json);
30+
printf("FAIL\n");
31+
retval=1;
32+
}
33+
json_object_put(string);
34+
return retval;
35+
}

test_null.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
JSON write result is correct: " \u0000 "
2+
PASS

test_null.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/sh
2+
3+
# Common definitions
4+
if test -z "$srcdir"; then
5+
srcdir="${0%/*}"
6+
test "$srcdir" = "$0" && srcdir=.
7+
test -z "$srcdir" && srcdir=.
8+
fi
9+
. "$srcdir/test-defs.sh"
10+
11+
run_output_test test_null
12+
exit $?

0 commit comments

Comments
 (0)