From 35d0a7cf850baea71e1e3e7680a6d861ddf8c1b2 Mon Sep 17 00:00:00 2001 From: Patrick Horn Date: Mon, 16 Jul 2012 15:15:57 -0700 Subject: [PATCH 1/2] Fix parse bug with numbers between 2^63 and 2^64-1. If a bad number is encountered, all numbers after it are set to INT_MAX until some syscall resets errno, which may or may not happen. This is caused by incorrect use of errno, which is unchanged if sscanf succeeds. In glibc, sscanf succeeds for int64 values between 2^63 and 2^64-1 despite the number being out of range. This causes the sanity check to fail. The check for ERANGE was incorrect -- if sscanf succeeds, it cannot change errno. Hence, the only place where ERANGE could be set is in the sanity check. --- json_util.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/json_util.c b/json_util.c index bab772b..cc20a43 100644 --- a/json_util.c +++ b/json_util.c @@ -167,8 +167,7 @@ int json_parse_int64(const char *buf, int64_t *retval) buf_skip_space++; if (buf_skip_space[0] == '0' && buf_skip_space[1] == '\0') orig_has_neg = 0; // "-0" is the same as just plain "0" - - if (errno != ERANGE) + { char buf_cmp[100]; char *buf_cmp_start = buf_cmp; @@ -196,16 +195,12 @@ int json_parse_int64(const char *buf, int64_t *retval) ) ) { - errno = ERANGE; + if (orig_has_neg) + num64 = INT64_MIN; + else + num64 = INT64_MAX; } } - if (errno == ERANGE) - { - if (orig_has_neg) - num64 = INT64_MIN; - else - num64 = INT64_MAX; - } *retval = num64; return 0; } From 1efafe10110304eef5de91bf0d7914c2a7575ed6 Mon Sep 17 00:00:00 2001 From: Patrick Horn Date: Tue, 17 Jul 2012 12:15:54 -0700 Subject: [PATCH 2/2] Handle \f which can sometimes be emitted by python --- json_tokener.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/json_tokener.c b/json_tokener.c index 47768f4..f5fa8d6 100644 --- a/json_tokener.c +++ b/json_tokener.c @@ -423,10 +423,12 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, case 'n': case 'r': case 't': + case 'f': if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1); else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1); else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1); else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1); + else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1); state = saved_state; break; case 'u':