Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop 17252a2de -> b192b3b9a


json decoding - fix array decoding bugs.

This commit fixes some broken behavior related to skipping of
whitespace.  It also fixes broken decoding of the following object
types:
    * array of unsigned integers
    * array of boolean


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/b192b3b9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/b192b3b9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/b192b3b9

Branch: refs/heads/develop
Commit: b192b3b9a7baac49da132ad76044348ddef837c1
Parents: 2752f23
Author: Christopher Collins <[email protected]>
Authored: Tue May 24 08:46:52 2016 -0700
Committer: Christopher Collins <[email protected]>
Committed: Tue May 24 08:49:22 2016 -0700

----------------------------------------------------------------------
 libs/json/src/json_decode.c | 121 +++++++++++++++++++++++----------------
 1 file changed, 71 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b192b3b9/libs/json/src/json_decode.c
----------------------------------------------------------------------
diff --git a/libs/json/src/json_decode.c b/libs/json/src/json_decode.c
index 78d1bc9..a7115ea 100644
--- a/libs/json/src/json_decode.c
+++ b/libs/json/src/json_decode.c
@@ -1,12 +1,14 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include <json/json.h>
+#include <assert.h>
 
-/** 
- * This file is based upon microjson, from Eric S Raymond. 
+#include "json/json.h"
+
+/**
+ * This file is based upon microjson, from Eric S Raymond.
  *
- * License information for MicroJSON is in the package file MSJSON_COPYING, 
- * it is BSD licensed source code. 
+ * License information for MicroJSON is in the package file MSJSON_COPYING,
+ * it is BSD licensed source code.
  */
 
 
@@ -78,8 +80,31 @@ PERMISSIONS
 #include <errno.h>
 #include <math.h>        /* for HUGE_VAL */
 
+static void
+json_skip_ws(struct json_buffer *jb)
+{
+    char c;
+
+    do {
+        c = jb->jb_read_next(jb);
+    } while (isspace(c));
+
+    jb->jb_read_prev(jb);
+}
+
+static char
+json_peek(struct json_buffer *jb)
+{
+    char c;
+
+    jb->jb_read_next(jb);
+    c = jb->jb_read_prev(jb);
+
+    return c;
+}
+
 static char *
-json_target_address(const struct json_attr_t *cursor, 
+json_target_address(const struct json_attr_t *cursor,
         const struct json_array_t *parent, int offset)
 {
     char *targetaddr = NULL;
@@ -120,19 +145,21 @@ json_target_address(const struct json_attr_t *cursor,
     return targetaddr;
 }
 
-static int 
-json_internal_read_object(struct json_buffer *jb, const struct json_attr_t 
*attrs, 
-        const struct json_array_t *parent, int offset)
+static int
+json_internal_read_object(struct json_buffer *jb,
+                          const struct json_attr_t *attrs,
+                          const struct json_array_t *parent,
+                          int offset)
 {
     char c;
-    enum { 
+    enum {
         init, await_attr, in_attr, await_value, in_val_string,
         in_escape, in_val_token, post_val, post_array
     } state = 0;
     char attrbuf[JSON_ATTR_MAX + 1], *pattr = NULL;
     char valbuf[JSON_VAL_MAX + 1], *pval = NULL;
     bool value_quoted = false;
-    char uescape[5];                /* enough space for 4 hex digits and a NUL 
*/
+    char uescape[5];    /* enough space for 4 hex digits and '\0' */
     const struct json_attr_t *cursor;
     int substatus, n, maxlen = 0;
     unsigned int u;
@@ -155,7 +182,8 @@ json_internal_read_object(struct json_buffer *jb, const 
struct json_attr_t *attr
                     memcpy(lptr, &cursor->dflt.integer, sizeof(long long int));
                     break;
                 case t_uinteger:
-                    memcpy(lptr, &cursor->dflt.uinteger, sizeof(long long 
unsigned int));
+                    memcpy(lptr, &cursor->dflt.uinteger,
+                           sizeof(long long unsigned int));
                     break;
                 case t_real:
                     memcpy(lptr, &cursor->dflt.real, sizeof(double));
@@ -365,7 +393,8 @@ json_internal_read_object(struct json_buffer *jb, const 
struct json_attr_t *attr
                     if (decimal && seeking == t_real) {
                         break;
                     }
-                    if (!decimal && (seeking == t_integer || seeking == 
t_uinteger)) {
+                    if (!decimal && (seeking == t_integer ||
+                                     seeking == t_uinteger)) {
                         break;
                     }
                 }
@@ -379,7 +408,7 @@ json_internal_read_object(struct json_buffer *jb, const 
struct json_attr_t *attr
             }
             if (value_quoted
                 && (cursor->type != t_string && cursor->type != t_character
-                    && cursor->type != t_check && cursor->type != t_ignore 
+                    && cursor->type != t_check && cursor->type != t_ignore
                     && cursor->map == 0)) {
                 return JSON_ERR_QNONSTRING;
             }
@@ -480,7 +509,7 @@ json_internal_read_object(struct json_buffer *jb, const 
struct json_attr_t *attr
     return 0;
 }
 
-int 
+int
 json_read_array(struct json_buffer *jb, const struct json_array_t *arr)
 {
     char valbuf[64];
@@ -489,41 +518,34 @@ json_read_array(struct json_buffer *jb, const struct 
json_array_t *arr)
     char *tp;
     int n, count;
 
-    for (c = jb->jb_read_next(jb); isspace((unsigned char)c);
-         c = jb->jb_read_next(jb)) {
-    }
+    json_skip_ws(jb);
 
-    if (c != '[') {
+    if (jb->jb_read_next(jb) != '[') {
         return JSON_ERR_ARRAYSTART;
-    } 
+    }
 
     tp = arr->arr.strings.store;
     arrcount = 0;
 
-    for (c = jb->jb_read_next(jb); isspace((unsigned char)c);
-         c = jb->jb_read_next(jb)) {
-    }
+    json_skip_ws(jb);
 
-    if (c == ']') {
+    if (json_peek(jb) == ']') {
         goto breakout;
     }
 
-    jb->jb_read_prev(jb);
     for (offset = 0; offset < arr->maxlen; offset++) {
+        json_skip_ws(jb);
+
         char *ep = NULL;
         switch (arr->element_type) {
         case t_string:
-            if (isspace((unsigned char) c)) {
-                c = jb->jb_read_next(jb);
-            }
-            if (c != '"') {
+            if (jb->jb_read_next(jb) != '"') {
                 return JSON_ERR_BADSTRING;
-            } else {
-                c = jb->jb_read_next(jb);
             }
             arr->arr.strings.ptrs[offset] = tp;
             for (; tp - arr->arr.strings.store < arr->arr.strings.storelen;
                  tp++) {
+                c = jb->jb_read_next(jb);
                 if (c == '"') {
                     c = jb->jb_read_next(jb);
                     *tp++ = '\0';
@@ -551,7 +573,7 @@ json_read_array(struct json_buffer *jb, const struct 
json_array_t *arr)
             n = jb->jb_readn(jb, valbuf, sizeof(valbuf)-1);
             valbuf[n] = '\0';
 
-            arr->arr.integers.store[offset] = (long long int)strtoll(valbuf, 
&ep, 0);
+            arr->arr.integers.store[offset] = strtoll(valbuf, &ep, 0);
             if (ep == valbuf) {
                 return JSON_ERR_BADNUM;
             } else {
@@ -559,20 +581,19 @@ json_read_array(struct json_buffer *jb, const struct 
json_array_t *arr)
                 while (count-- > 0) {
                     jb->jb_read_prev(jb);
                 }
-                c = jb->jb_read_next(jb);
             }
             break;
         case t_uinteger:
             n = jb->jb_readn(jb, valbuf, sizeof(valbuf)-1);
             valbuf[n] = '\0';
 
-            arr->arr.uintegers.store[offset] = (long long unsigned 
int)strtoull(valbuf, &ep, 0);
+            arr->arr.uintegers.store[offset] = strtoull(valbuf, &ep, 0);
             if (ep == valbuf) {
                 return JSON_ERR_BADNUM;
             } else {
-                count = ep - valbuf;
+                count = n - (ep - valbuf);
                 while (count-- > 0) {
-                    c = jb->jb_read_next(jb);
+                    jb->jb_read_prev(jb);
                 }
             }
             break;
@@ -600,17 +621,17 @@ json_read_array(struct json_buffer *jb, const struct 
json_array_t *arr)
 
             if (strncmp(valbuf, "true", 4) == 0) {
                 arr->arr.booleans.store[offset] = true;
-                count = 4;
-                while (count-- > 0) {
-                    c = jb->jb_read_next(jb);
-                }
-            }
-            else if (strncmp(valbuf, "false", 5) == 0) {
+                count = n - 4;
+            } else if (strncmp(valbuf, "false", 5) == 0) {
                 arr->arr.booleans.store[offset] = false;
-                count = 5;
-                while (count-- > 0) {
-                    c = jb->jb_read_next(jb);
-                }
+                count = n - 5;
+            } else {
+                return JSON_ERR_MISC;
+            }
+
+            assert(count >= 0);
+            while (count-- > 0) {
+                jb->jb_read_prev(jb);
             }
             break;
         case t_character:
@@ -620,9 +641,9 @@ json_read_array(struct json_buffer *jb, const struct 
json_array_t *arr)
             return JSON_ERR_SUBTYPE;
         }
         arrcount++;
-        if (isspace((unsigned char) c)) {
-            c = jb->jb_read_next(jb);
-        }
+        json_skip_ws(jb);
+
+        c = jb->jb_read_next(jb);
         if (c == ']') {
             goto breakout;
         } else if (c != ',') {
@@ -637,7 +658,7 @@ json_read_array(struct json_buffer *jb, const struct 
json_array_t *arr)
     return 0;
 }
 
-int 
+int
 json_read_object(struct json_buffer *jb, const struct json_attr_t *attrs)
 {
     int st;

Reply via email to