Skip to content

Commit 31578be

Browse files
authored
Import latest CJSON and libcbor. (#1223)
1 parent fbb2123 commit 31578be

File tree

18 files changed

+346
-92
lines changed

18 files changed

+346
-92
lines changed

THIRD-PARTY-LICENSES.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3434

3535
------
3636

37-
** cJSON; version 1.7.18 -- https://github.com/DaveGamble/cJSON
37+
** cJSON; version 1.7.19 -- https://github.com/DaveGamble/cJSON
3838
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
3939

4040
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -57,7 +57,7 @@ THE SOFTWARE.
5757

5858
------
5959

60-
** libcbor; version 0.12.0 -- https://github.com/PJK/libcbor
60+
** libcbor; version 0.13.0 -- https://github.com/PJK/libcbor
6161
Copyright (c) 2014-2017 Pavel Kalvoda
6262

6363
MIT License

scripts/import_libcbor.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def parse_version(version_string):
6464
/* Ignore the compiler warnings for libcbor. */
6565
#ifdef _MSC_VER
6666
# pragma warning(disable : 4028)
67+
# pragma warning(disable : 4189)
6768
# pragma warning(disable : 4715)
6869
# pragma warning(disable : 4232)
6970
# pragma warning(disable : 4068)

source/external/cJSON.c

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
127127
}
128128

129129
/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
130-
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 18)
130+
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 19)
131131
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
132132
#endif
133133

@@ -318,9 +318,11 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
318318
{
319319
double number = 0;
320320
unsigned char *after_end = NULL;
321-
unsigned char number_c_string[64];
321+
unsigned char *number_c_string;
322322
unsigned char decimal_point = get_decimal_point();
323323
size_t i = 0;
324+
size_t number_string_length = 0;
325+
cJSON_bool has_decimal_point = false;
324326

325327
if ((input_buffer == NULL) || (input_buffer->content == NULL))
326328
{
@@ -330,7 +332,7 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
330332
/* copy the number into a temporary buffer and replace '.' with the decimal point
331333
* of the current locale (for strtod)
332334
* This also takes care of '\0' not necessarily being available for marking the end of the input */
333-
for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
335+
for (i = 0; can_access_at_index(input_buffer, i); i++)
334336
{
335337
switch (buffer_at_offset(input_buffer)[i])
336338
{
@@ -348,23 +350,46 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
348350
case '-':
349351
case 'e':
350352
case 'E':
351-
number_c_string[i] = buffer_at_offset(input_buffer)[i];
353+
number_string_length++;
352354
break;
353355

354356
case '.':
355-
number_c_string[i] = decimal_point;
357+
number_string_length++;
358+
has_decimal_point = true;
356359
break;
357360

358361
default:
359362
goto loop_end;
360363
}
361364
}
362365
loop_end:
363-
number_c_string[i] = '\0';
366+
/* malloc for temporary buffer, add 1 for '\0' */
367+
number_c_string = (unsigned char *) input_buffer->hooks.allocate(number_string_length + 1);
368+
if (number_c_string == NULL)
369+
{
370+
return false; /* allocation failure */
371+
}
372+
373+
memcpy(number_c_string, buffer_at_offset(input_buffer), number_string_length);
374+
number_c_string[number_string_length] = '\0';
375+
376+
if (has_decimal_point)
377+
{
378+
for (i = 0; i < number_string_length; i++)
379+
{
380+
if (number_c_string[i] == '.')
381+
{
382+
/* replace '.' with the decimal point of the current locale (for strtod) */
383+
number_c_string[i] = decimal_point;
384+
}
385+
}
386+
}
364387

365388
number = strtod((const char*)number_c_string, (char**)&after_end);
366389
if (number_c_string == after_end)
367390
{
391+
/* free the temporary buffer */
392+
input_buffer->hooks.deallocate(number_c_string);
368393
return false; /* parse_error */
369394
}
370395

@@ -387,6 +412,8 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
387412
item->type = cJSON_Number;
388413

389414
input_buffer->offset += (size_t)(after_end - number_c_string);
415+
/* free the temporary buffer */
416+
input_buffer->hooks.deallocate(number_c_string);
390417
return true;
391418
}
392419

@@ -413,6 +440,8 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
413440
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
414441
{
415442
char *copy = NULL;
443+
size_t v1_len;
444+
size_t v2_len;
416445
/* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
417446
if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference))
418447
{
@@ -423,8 +452,17 @@ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
423452
{
424453
return NULL;
425454
}
426-
if (strlen(valuestring) <= strlen(object->valuestring))
455+
456+
v1_len = strlen(valuestring);
457+
v2_len = strlen(object->valuestring);
458+
459+
if (v1_len <= v2_len)
427460
{
461+
/* strcpy does not handle overlapping string: [X1, X2] [Y1, Y2] => X2 < Y1 or Y2 < X1 */
462+
if (!( valuestring + v1_len < object->valuestring || object->valuestring + v2_len < valuestring ))
463+
{
464+
return NULL;
465+
}
428466
strcpy(object->valuestring, valuestring);
429467
return object->valuestring;
430468
}
@@ -2218,7 +2256,7 @@ CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * c
22182256

22192257
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
22202258
{
2221-
if ((parent == NULL) || (item == NULL))
2259+
if ((parent == NULL) || (item == NULL) || (item != parent->child && item->prev == NULL))
22222260
{
22232261
return NULL;
22242262
}
@@ -2740,7 +2778,14 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int co
27402778
}
27412779

27422780
/* Duplication */
2781+
cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse);
2782+
27432783
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
2784+
{
2785+
return cJSON_Duplicate_rec(item, 0, recurse );
2786+
}
2787+
2788+
cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse)
27442789
{
27452790
cJSON *newitem = NULL;
27462791
cJSON *child = NULL;
@@ -2787,7 +2832,10 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
27872832
child = item->child;
27882833
while (child != NULL)
27892834
{
2790-
newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
2835+
if(depth >= CJSON_CIRCULAR_LIMIT) {
2836+
goto fail;
2837+
}
2838+
newchild = cJSON_Duplicate_rec(child, depth + 1, true); /* Duplicate (with recurse) each item in the ->next chain */
27912839
if (!newchild)
27922840
{
27932841
goto fail;

source/external/cJSON.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
8888
/* project version */
8989
#define CJSON_VERSION_MAJOR 1
9090
#define CJSON_VERSION_MINOR 7
91-
#define CJSON_VERSION_PATCH 18
91+
#define CJSON_VERSION_PATCH 19
9292

9393
#include <stddef.h>
9494

@@ -144,6 +144,12 @@ typedef int cJSON_bool;
144144
#define CJSON_NESTING_LIMIT 1000
145145
#endif
146146

147+
/* Limits the length of circular references can be before cJSON rejects to parse them.
148+
* This is to prevent stack overflows. */
149+
#ifndef CJSON_CIRCULAR_LIMIT
150+
#define CJSON_CIRCULAR_LIMIT 10000
151+
#endif
152+
147153
/* returns the version of cJSON as a string */
148154
CJSON_PUBLIC(const char*) cJSON_Version(void);
149155

source/external/libcbor/cbor.c

Lines changed: 145 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
* it under the terms of the MIT license. See LICENSE for details.
66
*/
77

8+
#include <stdbool.h>
9+
#include <string.h>
10+
811
#include "cbor.h"
912
#include "cbor/internal/builder_callbacks.h"
1013
#include "cbor/internal/loaders.h"
@@ -115,6 +118,9 @@ cbor_item_t* cbor_load(cbor_data source, size_t source_size,
115118
}
116119

117120
static cbor_item_t* _cbor_copy_int(cbor_item_t* item, bool negative) {
121+
CBOR_ASSERT(cbor_isa_uint(item) || cbor_isa_negint(item));
122+
CBOR_ASSERT(cbor_int_get_width(item) >= CBOR_INT_8 &&
123+
cbor_int_get_width(item) <= CBOR_INT_64);
118124
cbor_item_t* res = NULL;
119125
switch (cbor_int_get_width(item)) {
120126
case CBOR_INT_8:
@@ -137,6 +143,9 @@ static cbor_item_t* _cbor_copy_int(cbor_item_t* item, bool negative) {
137143
}
138144

139145
static cbor_item_t* _cbor_copy_float_ctrl(cbor_item_t* item) {
146+
CBOR_ASSERT(cbor_isa_float_ctrl(item));
147+
CBOR_ASSERT(cbor_float_get_width(item) >= CBOR_FLOAT_0 &&
148+
cbor_float_get_width(item) <= CBOR_FLOAT_64);
140149
switch (cbor_float_get_width(item)) {
141150
case CBOR_FLOAT_0:
142151
return cbor_build_ctrl(cbor_ctrl_value(item));
@@ -146,13 +155,14 @@ static cbor_item_t* _cbor_copy_float_ctrl(cbor_item_t* item) {
146155
return cbor_build_float4(cbor_float_get_float4(item));
147156
case CBOR_FLOAT_64:
148157
return cbor_build_float8(cbor_float_get_float8(item));
149-
default:
158+
default: // LCOV_EXCL_START
150159
_CBOR_UNREACHABLE;
151-
return NULL;
160+
return NULL; // LCOV_EXCL_START
152161
}
153162
}
154163

155164
cbor_item_t* cbor_copy(cbor_item_t* item) {
165+
CBOR_ASSERT_VALID_TYPE(cbor_typeof(item));
156166
switch (cbor_typeof(item)) {
157167
case CBOR_TYPE_UINT:
158168
return _cbor_copy_int(item, false);
@@ -283,9 +293,138 @@ cbor_item_t* cbor_copy(cbor_item_t* item) {
283293
}
284294
case CBOR_TYPE_FLOAT_CTRL:
285295
return _cbor_copy_float_ctrl(item);
286-
default:
296+
default: // LCOV_EXCL_START
297+
_CBOR_UNREACHABLE;
298+
return NULL; // LCOV_EXCL_STOP
299+
}
300+
}
301+
302+
cbor_item_t* cbor_copy_definite(cbor_item_t* item) {
303+
CBOR_ASSERT_VALID_TYPE(cbor_typeof(item));
304+
switch (cbor_typeof(item)) {
305+
case CBOR_TYPE_UINT:
306+
case CBOR_TYPE_NEGINT:
307+
return cbor_copy(item);
308+
case CBOR_TYPE_BYTESTRING:
309+
if (cbor_bytestring_is_definite(item)) {
310+
return cbor_copy(item);
311+
} else {
312+
size_t total_length = 0;
313+
for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) {
314+
total_length +=
315+
cbor_bytestring_length(cbor_bytestring_chunks_handle(item)[i]);
316+
}
317+
318+
unsigned char* combined_data = _cbor_malloc(total_length);
319+
if (combined_data == NULL) {
320+
return NULL;
321+
}
322+
323+
size_t offset = 0;
324+
for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) {
325+
cbor_item_t* chunk = cbor_bytestring_chunks_handle(item)[i];
326+
memcpy(combined_data + offset, cbor_bytestring_handle(chunk),
327+
cbor_bytestring_length(chunk));
328+
offset += cbor_bytestring_length(chunk);
329+
}
330+
331+
cbor_item_t* res = cbor_new_definite_bytestring();
332+
cbor_bytestring_set_handle(res, combined_data, total_length);
333+
return res;
334+
}
335+
case CBOR_TYPE_STRING:
336+
if (cbor_string_is_definite(item)) {
337+
return cbor_copy(item);
338+
} else {
339+
size_t total_length = 0;
340+
for (size_t i = 0; i < cbor_string_chunk_count(item); i++) {
341+
total_length +=
342+
cbor_string_length(cbor_string_chunks_handle(item)[i]);
343+
}
344+
345+
unsigned char* combined_data = _cbor_malloc(total_length);
346+
if (combined_data == NULL) {
347+
return NULL;
348+
}
349+
350+
size_t offset = 0;
351+
for (size_t i = 0; i < cbor_string_chunk_count(item); i++) {
352+
cbor_item_t* chunk = cbor_string_chunks_handle(item)[i];
353+
memcpy(combined_data + offset, cbor_string_handle(chunk),
354+
cbor_string_length(chunk));
355+
offset += cbor_string_length(chunk);
356+
}
357+
358+
cbor_item_t* res = cbor_new_definite_string();
359+
cbor_string_set_handle(res, combined_data, total_length);
360+
return res;
361+
}
362+
case CBOR_TYPE_ARRAY: {
363+
cbor_item_t* res = cbor_new_definite_array(cbor_array_size(item));
364+
if (res == NULL) {
365+
return NULL;
366+
}
367+
368+
for (size_t i = 0; i < cbor_array_size(item); i++) {
369+
cbor_item_t* entry_copy =
370+
cbor_copy_definite(cbor_array_handle(item)[i]);
371+
if (entry_copy == NULL) {
372+
cbor_decref(&res);
373+
return NULL;
374+
}
375+
// Cannot fail since we have a definite array preallocated
376+
// cppcheck-suppress syntaxError
377+
const bool item_pushed _CBOR_UNUSED = cbor_array_push(res, entry_copy);
378+
CBOR_ASSERT(item_pushed);
379+
cbor_decref(&entry_copy);
380+
}
381+
return res;
382+
}
383+
case CBOR_TYPE_MAP: {
384+
cbor_item_t* res;
385+
res = cbor_new_definite_map(cbor_map_size(item));
386+
if (res == NULL) {
387+
return NULL;
388+
}
389+
390+
struct cbor_pair* it = cbor_map_handle(item);
391+
for (size_t i = 0; i < cbor_map_size(item); i++) {
392+
cbor_item_t* key_copy = cbor_copy_definite(it[i].key);
393+
if (key_copy == NULL) {
394+
cbor_decref(&res);
395+
return NULL;
396+
}
397+
cbor_item_t* value_copy = cbor_copy_definite(it[i].value);
398+
if (value_copy == NULL) {
399+
cbor_decref(&res);
400+
cbor_decref(&key_copy);
401+
return NULL;
402+
}
403+
// Cannot fail since we have a definite map preallocated
404+
// cppcheck-suppress syntaxError
405+
const bool item_added _CBOR_UNUSED = cbor_map_add(
406+
res, (struct cbor_pair){.key = key_copy, .value = value_copy});
407+
CBOR_ASSERT(item_added);
408+
cbor_decref(&key_copy);
409+
cbor_decref(&value_copy);
410+
}
411+
return res;
412+
}
413+
case CBOR_TYPE_TAG: {
414+
cbor_item_t* item_copy =
415+
cbor_copy_definite(cbor_move(cbor_tag_item(item)));
416+
if (item_copy == NULL) {
417+
return NULL;
418+
}
419+
cbor_item_t* tag = cbor_build_tag(cbor_tag_value(item), item_copy);
420+
cbor_decref(&item_copy);
421+
return tag;
422+
}
423+
case CBOR_TYPE_FLOAT_CTRL:
424+
return cbor_copy(item);
425+
default: // LCOV_EXCL_START
287426
_CBOR_UNREACHABLE;
288-
return NULL;
427+
return NULL; // LCOV_EXCL_STOP
289428
}
290429
}
291430

@@ -309,6 +448,8 @@ static void _cbor_type_marquee(FILE* out, char* label, int indent) {
309448
}
310449

311450
static void _cbor_nested_describe(cbor_item_t* item, FILE* out, int indent) {
451+
CBOR_ASSERT(cbor_typeof(item) >= CBOR_TYPE_UINT &&
452+
cbor_typeof(item) <= CBOR_TYPE_FLOAT_CTRL);
312453
const int indent_offset = 4;
313454
switch (cbor_typeof(item)) {
314455
case CBOR_TYPE_UINT: {

0 commit comments

Comments
 (0)