소스 검색

Upgrade cJSON version to v1.7.16 (#2404)

Cengizhan Pasaoglu 2 년 전
부모
커밋
45a4e774de
3개의 변경된 파일429개의 추가작업 그리고 226개의 파일을 삭제
  1. 1 1
      ATTRIBUTIONS.md
  2. 334 160
      test-tools/host-tool/external/cJSON/cJSON.c
  3. 94 65
      test-tools/host-tool/external/cJSON/cJSON.h

+ 1 - 1
ATTRIBUTIONS.md

@@ -22,7 +22,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
 
 |  third party components | version number | latest release | vendor pages | CVE details |
 | --- | --- | --- | --- | --- |
-| cjson | 1.7.10 | 1.7.14 | https://github.com/DaveGamble/cJSON | https://www.cvedetails.com/vendor/19164/Cjson-Project.html |
+| cjson | 1.7.16 | 1.7.16 | https://github.com/DaveGamble/cJSON | https://www.cvedetails.com/vendor/19164/Cjson-Project.html |
 | contiki-ng (er-coap) | unspecified | 3.0 | https://github.com/contiki-os/contiki | https://www.cvedetails.com/vendor/16528/Contiki-os.html |
 | freebsd libm | unspecified | 13.0 | https://www.freebsd.org/ | https://www.cvedetails.com/vendor/6/Freebsd.html |
 | LVGL | 6.0.1 | 7.11.0 | https://lvgl.io/ | |

+ 334 - 160
test-tools/host-tool/external/cJSON/cJSON.c

@@ -1,24 +1,24 @@
 /*
- Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
+  Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+*/
 
 /* cJSON */
 /* JSON parser in C. */
@@ -43,6 +43,7 @@
 #include <stdlib.h>
 #include <limits.h>
 #include <ctype.h>
+#include <float.h>
 
 #ifdef ENABLE_LOCALES
 #include <locale.h>
@@ -58,9 +59,33 @@
 #include "cJSON.h"
 
 /* define our own boolean type */
+#ifdef true
+#undef true
+#endif
 #define true ((cJSON_bool)1)
+
+#ifdef false
+#undef false
+#endif
 #define false ((cJSON_bool)0)
 
+/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has
+ * been defined in math.h */
+#ifndef isinf
+#define isinf(d) (isnan((d - d)) && !isnan(d))
+#endif
+#ifndef isnan
+#define isnan(d) (d != d)
+#endif
+
+#ifndef NAN
+#ifdef _WIN32
+#define NAN sqrt(-1.0)
+#else
+#define NAN 0.0 / 0.0
+#endif
+#endif
+
 typedef struct {
     const unsigned char *json;
     size_t position;
@@ -72,7 +97,7 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
     return (const char *)(global_error.json + global_error.position);
 }
 
-CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item)
+CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON *const item)
 {
     if (!cJSON_IsString(item)) {
         return NULL;
@@ -81,18 +106,27 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item)
     return item->valuestring;
 }
 
+CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON *const item)
+{
+    if (!cJSON_IsNumber(item)) {
+        return (double)NAN;
+    }
+
+    return item->valuedouble;
+}
+
 /* This is a safeguard to prevent copy-pasters from using incompatible C and
  * header files */
 #if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) \
-    || (CJSON_VERSION_PATCH != 10)
+    || (CJSON_VERSION_PATCH != 16)
 #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
 #endif
 
 CJSON_PUBLIC(const char *) cJSON_Version(void)
 {
     static char version[15];
-    snprintf(version, sizeof(version), "%i.%i.%i", CJSON_VERSION_MAJOR,
-             CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
+    sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR,
+            CJSON_VERSION_PATCH);
 
     return version;
 }
@@ -127,8 +161,8 @@ typedef struct internal_hooks {
 } internal_hooks;
 
 #if defined(_MSC_VER)
-/* work around MSVC error C2322: '...' address of dillimport '...'
-   is not static */
+/* work around MSVC error C2322: '...' address of dllimport '...' is not static
+ */
 static void *CJSON_CDECL
 internal_malloc(size_t size)
 {
@@ -150,13 +184,11 @@ internal_realloc(void *pointer, size_t size)
 #define internal_realloc realloc
 #endif
 
-/* clang-format off */
-static internal_hooks global_hooks = {
-    internal_malloc,
-    internal_free,
-    internal_realloc
-};
-/* clang-format on */
+/* strlen of character literals resolved at compile time */
+#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
+
+static internal_hooks global_hooks = { internal_malloc, internal_free,
+                                       internal_realloc };
 
 static unsigned char *
 cJSON_strdup(const unsigned char *string, const internal_hooks *const hooks)
@@ -271,8 +303,8 @@ typedef struct {
 /* get a pointer to the buffer at the position */
 #define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
 
-/* Parse the input text to generate a number, and populate the result
-   into item. */
+/* Parse the input text to generate a number, and populate the result into item.
+ */
 static cJSON_bool
 parse_number(cJSON *const item, parse_buffer *const input_buffer)
 {
@@ -287,9 +319,8 @@ parse_number(cJSON *const item, parse_buffer *const input_buffer)
     }
 
     /* copy the number into a temporary buffer and replace '.' with the decimal
-     * point of the current locale (for strtod)
-     * This also takes care of '\0' not necessarily being available for marking
-     * the end of the input */
+     * point of the current locale (for strtod) This also takes care of '\0' not
+     * necessarily being available for marking the end of the input */
     for (i = 0; (i < (sizeof(number_c_string) - 1))
                 && can_access_at_index(input_buffer, i);
          i++) {
@@ -363,6 +394,32 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
     return object->valuedouble = number;
 }
 
+CJSON_PUBLIC(char *)
+cJSON_SetValuestring(cJSON *object, const char *valuestring)
+{
+    char *copy = NULL;
+    /* if object's type is not cJSON_String or is cJSON_IsReference, it should
+     * not set valuestring */
+    if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference)) {
+        return NULL;
+    }
+    if (strlen(valuestring) <= strlen(object->valuestring)) {
+        strcpy(object->valuestring, valuestring);
+        return object->valuestring;
+    }
+    copy =
+        (char *)cJSON_strdup((const unsigned char *)valuestring, &global_hooks);
+    if (copy == NULL) {
+        return NULL;
+    }
+    if (object->valuestring != NULL) {
+        cJSON_free(object->valuestring);
+    }
+    object->valuestring = copy;
+
+    return copy;
+}
+
 typedef struct {
     unsigned char *buffer;
     size_t length;
@@ -438,9 +495,8 @@ ensure(printbuffer *const p, size_t needed)
 
             return NULL;
         }
-        if (newbuffer) {
-            memcpy(newbuffer, p->buffer, p->offset + 1);
-        }
+
+        memcpy(newbuffer, p->buffer, p->offset + 1);
         p->hooks.deallocate(p->buffer);
     }
     p->length = newsize;
@@ -463,6 +519,14 @@ update_offset(printbuffer *const buffer)
     buffer->offset += strlen((const char *)buffer_pointer);
 }
 
+/* securely comparison of floating-point variables */
+static cJSON_bool
+compare_double(double a, double b)
+{
+    double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b);
+    return (fabs(a - b) <= maxVal * DBL_EPSILON);
+}
+
 /* Render the number nicely from the given item into a string. */
 static cJSON_bool
 print_number(const cJSON *const item, printbuffer *const output_buffer)
@@ -471,35 +535,37 @@ print_number(const cJSON *const item, printbuffer *const output_buffer)
     double d = item->valuedouble;
     int length = 0;
     size_t i = 0;
-    unsigned char
-        number_buffer[26]; /* temporary buffer to print the number into */
+    unsigned char number_buffer[26] = {
+        0
+    }; /* temporary buffer to print the number into */
     unsigned char decimal_point = get_decimal_point();
-    double test;
+    double test = 0.0;
 
     if (output_buffer == NULL) {
         return false;
     }
 
     /* This checks for NaN and Infinity */
-    if ((d * 0) != 0) {
-        length = snprintf((char *)number_buffer, sizeof(number_buffer), "null");
+    if (isnan(d) || isinf(d)) {
+        length = sprintf((char *)number_buffer, "null");
+    }
+    else if (d == (double)item->valueint) {
+        length = sprintf((char *)number_buffer, "%d", item->valueint);
     }
     else {
         /* Try 15 decimal places of precision to avoid nonsignificant nonzero
          * digits */
-        length =
-            snprintf((char *)number_buffer, sizeof(number_buffer), "%1.15g", d);
+        length = sprintf((char *)number_buffer, "%1.15g", d);
 
         /* Check whether the original double can be recovered */
         if ((sscanf((char *)number_buffer, "%lg", &test) != 1)
-            || ((double)test != d)) {
+            || !compare_double((double)test, d)) {
             /* If not, print with 17 decimal places of precision */
-            length = snprintf((char *)number_buffer, sizeof(number_buffer),
-                              "%1.17g", d);
+            length = sprintf((char *)number_buffer, "%1.17g", d);
         }
     }
 
-    /* snprintf failed or buffer overrun occured */
+    /* sprintf failed or buffer overrun occurred */
     if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) {
         return false;
     }
@@ -709,8 +775,7 @@ parse_string(cJSON *const item, parse_buffer *const input_buffer)
         if (((size_t)(input_end - input_buffer->content)
              >= input_buffer->length)
             || (*input_end != '\"')) {
-            goto fail;
-            /* string ended unexpectedly */
+            goto fail; /* string ended unexpectedly */
         }
 
         /* This is at most how much we need for the output */
@@ -719,8 +784,7 @@ parse_string(cJSON *const item, parse_buffer *const input_buffer)
         output = (unsigned char *)input_buffer->hooks.allocate(allocation_length
                                                                + sizeof(""));
         if (output == NULL) {
-            goto fail;
-            /* allocation failure */
+            goto fail; /* allocation failure */
         }
     }
 
@@ -759,7 +823,7 @@ parse_string(cJSON *const item, parse_buffer *const input_buffer)
                     *output_pointer++ = input_pointer[1];
                     break;
 
-                    /* UTF-16 literal */
+                /* UTF-16 literal */
                 case 'u':
                     sequence_length = utf16_literal_to_utf8(
                         input_pointer, input_end, &output_pointer);
@@ -805,7 +869,7 @@ print_string_ptr(const unsigned char *const input,
                  printbuffer *const output_buffer)
 {
     const unsigned char *input_pointer = NULL;
-    unsigned char *output = NULL, *output_end;
+    unsigned char *output = NULL;
     unsigned char *output_pointer = NULL;
     size_t output_length = 0;
     /* numbers of additional characters needed for escaping */
@@ -853,7 +917,6 @@ print_string_ptr(const unsigned char *const input,
     if (output == NULL) {
         return false;
     }
-    output_end = output + output_length + sizeof("\"\"");
 
     /* no characters have to be escaped */
     if (escape_characters == 0) {
@@ -902,9 +965,7 @@ print_string_ptr(const unsigned char *const input,
                     break;
                 default:
                     /* escape and print as unicode codepoint */
-                    snprintf((char *)output_pointer,
-                             output_end - output_pointer, "u%04x",
-                             *input_pointer);
+                    sprintf((char *)output_pointer, "u%04x", *input_pointer);
                     output_pointer += 4;
                     break;
             }
@@ -945,6 +1006,10 @@ buffer_skip_whitespace(parse_buffer *const buffer)
         return NULL;
     }
 
+    if (cannot_access_at_index(buffer, 0)) {
+        return buffer;
+    }
+
     while (can_access_at_index(buffer, 0)
            && (buffer_at_offset(buffer)[0] <= 32)) {
         buffer->offset++;
@@ -975,10 +1040,28 @@ skip_utf8_bom(parse_buffer *const buffer)
     return buffer;
 }
 
-/* Parse an object - create a new root, and populate. */
 CJSON_PUBLIC(cJSON *)
 cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
                     cJSON_bool require_null_terminated)
+{
+    size_t buffer_length;
+
+    if (NULL == value) {
+        return NULL;
+    }
+
+    /* Adding null character size due to require_null_terminated. */
+    buffer_length = strlen(value) + sizeof("");
+
+    return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end,
+                                     require_null_terminated);
+}
+
+/* Parse an object - create a new root, and populate. */
+CJSON_PUBLIC(cJSON *)
+cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length,
+                          const char **return_parse_end,
+                          cJSON_bool require_null_terminated)
 {
     parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
     cJSON *item = NULL;
@@ -987,12 +1070,12 @@ cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
     global_error.json = NULL;
     global_error.position = 0;
 
-    if (value == NULL) {
+    if (value == NULL || 0 == buffer_length) {
         goto fail;
     }
 
     buffer.content = (const unsigned char *)value;
-    buffer.length = strlen((const char *)value) + sizeof("");
+    buffer.length = buffer_length;
     buffer.offset = 0;
     buffer.hooks = global_hooks;
 
@@ -1056,7 +1139,13 @@ CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
     return cJSON_ParseWithOpts(value, 0, 0);
 }
 
-#define cjson_min(a, b) ((a < b) ? a : b)
+CJSON_PUBLIC(cJSON *)
+cJSON_ParseWithLength(const char *value, size_t buffer_length)
+{
+    return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0);
+}
+
+#define cjson_min(a, b) (((a) < (b)) ? (a) : (b))
 
 static unsigned char *
 print(const cJSON *const item, cJSON_bool format,
@@ -1113,6 +1202,10 @@ fail:
         hooks->deallocate(buffer->buffer);
     }
 
+    if (printed != NULL) {
+        hooks->deallocate(printed);
+    }
+
     return NULL;
 }
 
@@ -1156,20 +1249,20 @@ cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
 }
 
 CJSON_PUBLIC(cJSON_bool)
-cJSON_PrintPreallocated(cJSON *item, char *buf, const int len,
-                        const cJSON_bool fmt)
+cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length,
+                        const cJSON_bool format)
 {
     printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
 
-    if ((len < 0) || (buf == NULL)) {
+    if ((length < 0) || (buffer == NULL)) {
         return false;
     }
 
-    p.buffer = (unsigned char *)buf;
-    p.length = (size_t)len;
+    p.buffer = (unsigned char *)buffer;
+    p.length = (size_t)length;
     p.offset = 0;
     p.noalloc = true;
-    p.format = fmt;
+    p.format = format;
     p.hooks = global_hooks;
 
     return print_value(item, &p);
@@ -1341,8 +1434,7 @@ parse_array(cJSON *const item, parse_buffer *const input_buffer)
         /* allocate next item */
         cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
         if (new_item == NULL) {
-            goto fail;
-            /* allocation failure */
+            goto fail; /* allocation failure */
         }
 
         /* attach next item to list */
@@ -1361,8 +1453,7 @@ parse_array(cJSON *const item, parse_buffer *const input_buffer)
         input_buffer->offset++;
         buffer_skip_whitespace(input_buffer);
         if (!parse_value(current_item, input_buffer)) {
-            goto fail;
-            /* failed to parse value */
+            goto fail; /* failed to parse value */
         }
         buffer_skip_whitespace(input_buffer);
     } while (can_access_at_index(input_buffer, 0)
@@ -1370,13 +1461,16 @@ parse_array(cJSON *const item, parse_buffer *const input_buffer)
 
     if (cannot_access_at_index(input_buffer, 0)
         || buffer_at_offset(input_buffer)[0] != ']') {
-        goto fail;
-        /* expected end of array */
+        goto fail; /* expected end of array */
     }
 
 success:
     input_buffer->depth--;
 
+    if (head != NULL) {
+        head->prev = current_item;
+    }
+
     item->type = cJSON_Array;
     item->child = head;
 
@@ -1461,16 +1555,14 @@ parse_object(cJSON *const item, parse_buffer *const input_buffer)
 
     if (cannot_access_at_index(input_buffer, 0)
         || (buffer_at_offset(input_buffer)[0] != '{')) {
-        goto fail;
-        /* not an object */
+        goto fail; /* not an object */
     }
 
     input_buffer->offset++;
     buffer_skip_whitespace(input_buffer);
     if (can_access_at_index(input_buffer, 0)
         && (buffer_at_offset(input_buffer)[0] == '}')) {
-        goto success;
-        /* empty object */
+        goto success; /* empty object */
     }
 
     /* check if we skipped to the end of the buffer */
@@ -1486,8 +1578,7 @@ parse_object(cJSON *const item, parse_buffer *const input_buffer)
         /* allocate next item */
         cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
         if (new_item == NULL) {
-            goto fail;
-            /* allocation failure */
+            goto fail; /* allocation failure */
         }
 
         /* attach next item to list */
@@ -1506,8 +1597,7 @@ parse_object(cJSON *const item, parse_buffer *const input_buffer)
         input_buffer->offset++;
         buffer_skip_whitespace(input_buffer);
         if (!parse_string(current_item, input_buffer)) {
-            goto fail;
-            /* faile to parse name */
+            goto fail; /* failed to parse name */
         }
         buffer_skip_whitespace(input_buffer);
 
@@ -1517,16 +1607,14 @@ parse_object(cJSON *const item, parse_buffer *const input_buffer)
 
         if (cannot_access_at_index(input_buffer, 0)
             || (buffer_at_offset(input_buffer)[0] != ':')) {
-            goto fail;
-            /* invalid object */
+            goto fail; /* invalid object */
         }
 
         /* parse the value */
         input_buffer->offset++;
         buffer_skip_whitespace(input_buffer);
         if (!parse_value(current_item, input_buffer)) {
-            goto fail;
-            /* failed to parse value */
+            goto fail; /* failed to parse value */
         }
         buffer_skip_whitespace(input_buffer);
     } while (can_access_at_index(input_buffer, 0)
@@ -1534,13 +1622,16 @@ parse_object(cJSON *const item, parse_buffer *const input_buffer)
 
     if (cannot_access_at_index(input_buffer, 0)
         || (buffer_at_offset(input_buffer)[0] != '}')) {
-        goto fail;
-        /* expected end of object */
+        goto fail; /* expected end of object */
     }
 
 success:
     input_buffer->depth--;
 
+    if (head != NULL) {
+        head->prev = current_item;
+    }
+
     item->type = cJSON_Object;
     item->child = head;
 
@@ -1792,22 +1883,26 @@ add_item_to_array(cJSON *array, cJSON *item)
 {
     cJSON *child = NULL;
 
-    if ((item == NULL) || (array == NULL)) {
+    if ((item == NULL) || (array == NULL) || (array == item)) {
         return false;
     }
 
     child = array->child;
-
+    /*
+     * To find the last item in array quickly, we use prev in array
+     */
     if (child == NULL) {
         /* list is empty, start new one */
         array->child = item;
+        item->prev = item;
+        item->next = NULL;
     }
     else {
         /* append to the end */
-        while (child->next) {
-            child = child->next;
+        if (child->prev) {
+            suffix_object(child->prev, item);
+            array->child->prev = item;
         }
-        suffix_object(child, item);
     }
 
     return true;
@@ -1847,7 +1942,8 @@ add_item_to_object(cJSON *const object, const char *const string,
     char *new_key = NULL;
     int new_type = cJSON_Invalid;
 
-    if ((object == NULL) || (string == NULL) || (item == NULL)) {
+    if ((object == NULL) || (string == NULL) || (item == NULL)
+        || (object == item)) {
         return false;
     }
 
@@ -2028,7 +2124,7 @@ cJSON_DetachItemViaPointer(cJSON *parent, cJSON *const item)
         return NULL;
     }
 
-    if (item->prev != NULL) {
+    if (item != parent->child) {
         /* not the first element */
         item->prev->next = item->next;
     }
@@ -2041,6 +2137,11 @@ cJSON_DetachItemViaPointer(cJSON *parent, cJSON *const item)
         /* first element */
         parent->child = item->next;
     }
+    else if (item->next == NULL) {
+        /* last element */
+        parent->child->prev = item->prev;
+    }
+
     /* make sure the detached item doesn't point anywhere anymore */
     item->prev = NULL;
     item->next = NULL;
@@ -2121,7 +2222,8 @@ CJSON_PUBLIC(cJSON_bool)
 cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
                             cJSON *replacement)
 {
-    if ((parent == NULL) || (replacement == NULL) || (item == NULL)) {
+    if ((parent == NULL) || (parent->child == NULL) || (replacement == NULL)
+        || (item == NULL)) {
         return false;
     }
 
@@ -2135,12 +2237,24 @@ cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
     if (replacement->next != NULL) {
         replacement->next->prev = replacement;
     }
-    if (replacement->prev != NULL) {
-        replacement->prev->next = replacement;
-    }
     if (parent->child == item) {
+        if (parent->child->prev == parent->child) {
+            replacement->prev = replacement;
+        }
         parent->child = replacement;
     }
+    else { /*
+            * To find the last item in array quickly, we use prev in array.
+            * We can't modify the last item's next pointer where this item was
+            * the parent's child
+            */
+        if (replacement->prev != NULL) {
+            replacement->prev->next = replacement;
+        }
+        if (replacement->next == NULL) {
+            parent->child->prev = replacement;
+        }
+    }
 
     item->next = NULL;
     item->prev = NULL;
@@ -2149,15 +2263,15 @@ cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
     return true;
 }
 
-CJSON_PUBLIC(void)
+CJSON_PUBLIC(cJSON_bool)
 cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
 {
     if (which < 0) {
-        return;
+        return false;
     }
 
-    cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which),
-                                newitem);
+    return cJSON_ReplaceItemViaPointer(
+        array, get_array_item(array, (size_t)which), newitem);
 }
 
 static cJSON_bool
@@ -2175,25 +2289,27 @@ replace_item_in_object(cJSON *object, const char *string, cJSON *replacement,
     }
     replacement->string =
         (char *)cJSON_strdup((const unsigned char *)string, &global_hooks);
+    if (replacement->string == NULL) {
+        return false;
+    }
+
     replacement->type &= ~cJSON_StringIsConst;
 
-    cJSON_ReplaceItemViaPointer(
+    return cJSON_ReplaceItemViaPointer(
         object, get_object_item(object, string, case_sensitive), replacement);
-
-    return true;
 }
 
-CJSON_PUBLIC(void)
+CJSON_PUBLIC(cJSON_bool)
 cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
 {
-    replace_item_in_object(object, string, newitem, false);
+    return replace_item_in_object(object, string, newitem, false);
 }
 
-CJSON_PUBLIC(void)
+CJSON_PUBLIC(cJSON_bool)
 cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string,
                                        cJSON *newitem)
 {
-    replace_item_in_object(object, string, newitem, true);
+    return replace_item_in_object(object, string, newitem, true);
 }
 
 /* Create basic types: */
@@ -2227,11 +2343,11 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
     return item;
 }
 
-CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b)
+CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean)
 {
     cJSON *item = cJSON_New_Item(&global_hooks);
     if (item) {
-        item->type = b ? cJSON_True : cJSON_False;
+        item->type = boolean ? cJSON_True : cJSON_False;
     }
 
     return item;
@@ -2357,6 +2473,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
     }
 
     a = cJSON_CreateArray();
+
     for (i = 0; a && (i < (size_t)count); i++) {
         n = cJSON_CreateNumber(numbers[i]);
         if (!n) {
@@ -2372,6 +2489,10 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
         p = n;
     }
 
+    if (a && a->child) {
+        a->child->prev = n;
+    }
+
     return a;
 }
 
@@ -2403,6 +2524,10 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
         p = n;
     }
 
+    if (a && a->child) {
+        a->child->prev = n;
+    }
+
     return a;
 }
 
@@ -2434,10 +2559,15 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
         p = n;
     }
 
+    if (a && a->child) {
+        a->child->prev = n;
+    }
+
     return a;
 }
 
-CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count)
+CJSON_PUBLIC(cJSON *)
+cJSON_CreateStringArray(const char *const *strings, int count)
 {
     size_t i = 0;
     cJSON *n = NULL;
@@ -2465,6 +2595,10 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count)
         p = n;
     }
 
+    if (a && a->child) {
+        a->child->prev = n;
+    }
+
     return a;
 }
 
@@ -2532,6 +2666,9 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
         }
         child = child->next;
     }
+    if (newitem && newitem->child) {
+        newitem->child->prev = newchild;
+    }
 
     return newitem;
 
@@ -2543,55 +2680,93 @@ fail:
     return NULL;
 }
 
-CJSON_PUBLIC(void) cJSON_Minify(char *json)
+static void
+skip_oneline_comment(char **input)
 {
-    unsigned char *into = (unsigned char *)json;
+    *input += static_strlen("//");
 
-    if (json == NULL) {
-        return;
+    for (; (*input)[0] != '\0'; ++(*input)) {
+        if ((*input)[0] == '\n') {
+            *input += static_strlen("\n");
+            return;
+        }
     }
+}
 
-    while (*json) {
-        if (*json == ' ') {
-            json++;
-        }
-        else if (*json == '\t') {
-            /* Whitespace characters. */
-            json++;
-        }
-        else if (*json == '\r') {
-            json++;
+static void
+skip_multiline_comment(char **input)
+{
+    *input += static_strlen("/*");
+
+    for (; (*input)[0] != '\0'; ++(*input)) {
+        if (((*input)[0] == '*') && ((*input)[1] == '/')) {
+            *input += static_strlen("*/");
+            return;
         }
-        else if (*json == '\n') {
-            json++;
+    }
+}
+
+static void
+minify_string(char **input, char **output)
+{
+    (*output)[0] = (*input)[0];
+    *input += static_strlen("\"");
+    *output += static_strlen("\"");
+
+    for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
+        (*output)[0] = (*input)[0];
+
+        if ((*input)[0] == '\"') {
+            (*output)[0] = '\"';
+            *input += static_strlen("\"");
+            *output += static_strlen("\"");
+            return;
         }
-        else if ((*json == '/') && (json[1] == '/')) {
-            /* double-slash comments, to end of line. */
-            while (*json && (*json != '\n')) {
-                json++;
-            }
+        else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) {
+            (*output)[1] = (*input)[1];
+            *input += static_strlen("\"");
+            *output += static_strlen("\"");
         }
-        else if ((*json == '/') && (json[1] == '*')) {
-            /* multiline comments. */
-            while (*json && !((*json == '*') && (json[1] == '/'))) {
+    }
+}
+
+CJSON_PUBLIC(void) cJSON_Minify(char *json)
+{
+    char *into = json;
+
+    if (json == NULL) {
+        return;
+    }
+
+    while (json[0] != '\0') {
+        switch (json[0]) {
+            case ' ':
+            case '\t':
+            case '\r':
+            case '\n':
                 json++;
-            }
-            json += 2;
-        }
-        else if (*json == '\"') {
-            /* string literals, which are \" sensitive. */
-            *into++ = (unsigned char)*json++;
-            while (*json && (*json != '\"')) {
-                if (*json == '\\') {
-                    *into++ = (unsigned char)*json++;
+                break;
+
+            case '/':
+                if (json[1] == '/') {
+                    skip_oneline_comment(&json);
                 }
-                *into++ = (unsigned char)*json++;
-            }
-            *into++ = (unsigned char)*json++;
-        }
-        else {
-            /* All other characters. */
-            *into++ = (unsigned char)*json++;
+                else if (json[1] == '*') {
+                    skip_multiline_comment(&json);
+                }
+                else {
+                    json++;
+                }
+                break;
+
+            case '\"':
+                minify_string(&json, (char **)&into);
+                break;
+
+            default:
+                into[0] = json[0];
+                json++;
+                into++;
         }
     }
 
@@ -2692,8 +2867,7 @@ CJSON_PUBLIC(cJSON_bool)
 cJSON_Compare(const cJSON *const a, const cJSON *const b,
               const cJSON_bool case_sensitive)
 {
-    if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))
-        || cJSON_IsInvalid(a)) {
+    if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))) {
         return false;
     }
 
@@ -2726,7 +2900,7 @@ cJSON_Compare(const cJSON *const a, const cJSON *const b,
             return true;
 
         case cJSON_Number:
-            if (a->valuedouble == b->valuedouble) {
+            if (compare_double(a->valuedouble, b->valuedouble)) {
                 return true;
             }
             return false;

+ 94 - 65
test-tools/host-tool/external/cJSON/cJSON.h

@@ -1,24 +1,24 @@
 /*
- Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
+  Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+*/
 
 #ifndef cJSON__h
 #define cJSON__h
@@ -35,30 +35,34 @@ extern "C" {
 
 #ifdef __WINDOWS__
 
-/**
- * When compiling for windows, we specify a specific calling convention to avoid
- * issues where we are being called from a project with a different default
- * calling convention. For windows you have 3 define options:
- *   CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever
- *                        dllexport symbols
- *   CJSON_EXPORT_SYMBOLS - Define this on library build when you want to
- *                          dllexport symbols (default)
- *   CJSON_IMPORT_SYMBOLS - Define this if you  want to dllimport symbol
- *
- * For *nix builds that support visibility attribute, you can define similar
- * behavior by setting default visibility to hidden by adding
- *   -fvisibility=hidden (for gcc)
- * or
- *   -xldscope=hidden (for sun cc)
- * to CFLAGS, then using the CJSON_API_VISIBILITY flag to "export" the same
- * symbols the way CJSON_EXPORT_SYMBOLS does
- */
+/* When compiling for windows, we specify a specific calling convention to avoid
+issues where we are being called from a project with a different default calling
+convention.  For windows you have 3 define options:
+
+CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever
+dllexport symbols CJSON_EXPORT_SYMBOLS - Define this on library build when you
+want to dllexport symbols (default) CJSON_IMPORT_SYMBOLS - Define this if you
+want to dllimport symbol
+
+For *nix builds that support visibility attribute, you can define similar
+behavior by
+
+setting default visibility to hidden by adding
+-fvisibility=hidden (for gcc)
+or
+-xldscope=hidden (for sun cc)
+to CFLAGS
+
+then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way
+CJSON_EXPORT_SYMBOLS does
+
+*/
 
 #define CJSON_CDECL __cdecl
 #define CJSON_STDCALL __stdcall
 
 /* export symbols by default, this is necessary for copy pasting the C and
-   header file */
+ * header file */
 #if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) \
     && !defined(CJSON_EXPORT_SYMBOLS)
 #define CJSON_EXPORT_SYMBOLS
@@ -86,7 +90,7 @@ extern "C" {
 /* project version */
 #define CJSON_VERSION_MAJOR 1
 #define CJSON_VERSION_MINOR 7
-#define CJSON_VERSION_PATCH 10
+#define CJSON_VERSION_PATCH 16
 
 #include <stddef.h>
 
@@ -107,11 +111,11 @@ extern "C" {
 /* The cJSON structure: */
 typedef struct cJSON {
     /* next/prev allow you to walk array/object chains. Alternatively, use
-       GetArraySize/GetArrayItem/GetObjectItem */
+     * GetArraySize/GetArrayItem/GetObjectItem */
     struct cJSON *next;
     struct cJSON *prev;
     /* An array or object item will have a child pointer pointing to a chain of
-       the items in the array/object. */
+     * the items in the array/object. */
     struct cJSON *child;
 
     /* The type of the item, as above. */
@@ -125,7 +129,7 @@ typedef struct cJSON {
     double valuedouble;
 
     /* The item's name string, if this item is the child of, or is in the list
-       of subitems of an object. */
+     * of subitems of an object. */
     char *string;
 } cJSON;
 
@@ -140,7 +144,7 @@ typedef struct cJSON_Hooks {
 typedef int cJSON_bool;
 
 /* Limits how deeply nested arrays/objects can be before cJSON rejects to parse
-   them. This is to prevent stack overflows. */
+ * them. This is to prevent stack overflows. */
 #ifndef CJSON_NESTING_LIMIT
 #define CJSON_NESTING_LIMIT 1000
 #endif
@@ -159,6 +163,8 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks *hooks);
 /* Supply a block of JSON, and this returns a cJSON object you can interrogate.
  */
 CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
+CJSON_PUBLIC(cJSON *)
+cJSON_ParseWithLength(const char *value, size_t buffer_length);
 /* ParseWithOpts allows you to require (and check) that the JSON is null
  * terminated, and to retrieve the pointer to the final byte parsed. */
 /* If you supply a ptr in return_parse_end and parsing fails, then
@@ -167,6 +173,10 @@ CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
 CJSON_PUBLIC(cJSON *)
 cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
                     cJSON_bool require_null_terminated);
+CJSON_PUBLIC(cJSON *)
+cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length,
+                          const char **return_parse_end,
+                          cJSON_bool require_null_terminated);
 
 /* Render a cJSON entity to text for transfer/storage. */
 CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
@@ -185,7 +195,7 @@ CJSON_PUBLIC(cJSON_bool)
 cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length,
                         const cJSON_bool format);
 /* Delete a cJSON entity and all subentities. */
-CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
+CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
 
 /* Returns the number of items in an array (or object). */
 CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
@@ -205,8 +215,9 @@ cJSON_HasObjectItem(const cJSON *object, const char *string);
  * when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
 CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
 
-/* Check if the item is a string and return its valuestring */
-CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
+/* Check item type and return its value */
+CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON *const item);
+CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON *const item);
 
 /* These functions check the type of an item */
 CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON *const item);
@@ -233,18 +244,21 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
 CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
 
 /* Create a string where valuestring references a string so
-   it will not be freed by cJSON_Delete */
+ * it will not be freed by cJSON_Delete */
 CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
-/* Create an object/arrray that only references it's elements so
-   they will not be freed by cJSON_Delete */
+/* Create an object/array that only references it's elements so
+ * they will not be freed by cJSON_Delete */
 CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
 CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
 
-/* These utilities create an Array of count items. */
+/* These utilities create an Array of count items.
+ * The parameter count cannot be greater than the number of elements in the
+ * number array, otherwise array access will be out of bounds.*/
 CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
 CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
 CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
-CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
+CJSON_PUBLIC(cJSON *)
+cJSON_CreateStringArray(const char *const *strings, int count);
 
 /* Append item to the specified array/object. */
 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
@@ -264,7 +278,7 @@ cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
 CJSON_PUBLIC(cJSON_bool)
 cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
 
-/* Remove/Detatch items from Arrays/Objects. */
+/* Remove/Detach items from Arrays/Objects. */
 CJSON_PUBLIC(cJSON *)
 cJSON_DetachItemViaPointer(cJSON *parent, cJSON *const item);
 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
@@ -286,32 +300,35 @@ cJSON_InsertItemInArray(
 CJSON_PUBLIC(cJSON_bool)
 cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
                             cJSON *replacement);
-CJSON_PUBLIC(void)
+CJSON_PUBLIC(cJSON_bool)
 cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
-CJSON_PUBLIC(void)
+CJSON_PUBLIC(cJSON_bool)
 cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
-CJSON_PUBLIC(void)
+CJSON_PUBLIC(cJSON_bool)
 cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string,
                                        cJSON *newitem);
 
 /* Duplicate a cJSON item */
 CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
 /* Duplicate will create a new, identical cJSON item to the one you pass, in new
- memory that will need to be released. With recurse!=0, it will duplicate any
- children connected to the item. The item->next and ->prev pointers are always
- zero on return from Duplicate. */
+ * memory that will need to be released. With recurse!=0, it will duplicate any
+ * children connected to the item. The item->next and ->prev pointers are always
+ * zero on return from Duplicate. */
 /* Recursively compare two cJSON items for equality. If either a or b is NULL or
- * invalid, they will be considered unequal.
- * case_sensitive determines if object keys are treated case sensitive (1) or
- * case insensitive (0) */
+ * invalid, they will be considered unequal. case_sensitive determines if object
+ * keys are treated case sensitive (1) or case insensitive (0) */
 CJSON_PUBLIC(cJSON_bool)
 cJSON_Compare(const cJSON *const a, const cJSON *const b,
               const cJSON_bool case_sensitive);
 
+/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from
+ * strings. The input pointer json cannot point to a read-only address area,
+ * such as a string constant, but should point to a readable and writable
+ * address area. */
 CJSON_PUBLIC(void) cJSON_Minify(char *json);
 
 /* Helper functions for creating and adding items to an object at the same time.
-   They return the added item or NULL on failure. */
+ * They return the added item or NULL on failure. */
 CJSON_PUBLIC(cJSON *)
 cJSON_AddNullToObject(cJSON *const object, const char *const name);
 CJSON_PUBLIC(cJSON *)
@@ -336,7 +353,7 @@ CJSON_PUBLIC(cJSON *)
 cJSON_AddArrayToObject(cJSON *const object, const char *const name);
 
 /* When assigning an integer value, it needs to be propagated to valuedouble
-   too. */
+ * too. */
 #define cJSON_SetIntValue(object, number)                             \
     ((object) ? (object)->valueint = (object)->valuedouble = (number) \
               : (number))
@@ -345,6 +362,18 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
 #define cJSON_SetNumberValue(object, number)                          \
     ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) \
                       : (number))
+/* Change the valuestring of a cJSON_String object, only takes effect when type
+ * of object is cJSON_String */
+CJSON_PUBLIC(char *)
+cJSON_SetValuestring(cJSON *object, const char *valuestring);
+
+/* If the object is not a boolean type this does nothing and returns
+ * cJSON_Invalid else it returns the new type*/
+#define cJSON_SetBoolValue(object, boolValue)                                \
+    ((object != NULL && ((object)->type & (cJSON_False | cJSON_True)))       \
+         ? (object)->type = ((object)->type & (~(cJSON_False | cJSON_True))) \
+                            | ((boolValue) ? cJSON_True : cJSON_False)       \
+         : cJSON_Invalid)
 
 /* Macro for iterating over an array or object */
 #define cJSON_ArrayForEach(element, array)                                   \
@@ -352,7 +381,7 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
          element = element->next)
 
 /* malloc/free objects using the malloc/free functions that have been set with
-   cJSON_InitHooks */
+ * cJSON_InitHooks */
 CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
 CJSON_PUBLIC(void) cJSON_free(void *object);