Skip to content

Commit

Permalink
Merge pull request #249 from DaveGamble/fix-add-item
Browse files Browse the repository at this point in the history
Release 1.7.4
  • Loading branch information
FSMaxB authored Mar 2, 2018
2 parents a559eac + 5da9edc commit 6f264b5
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 16 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
1.7.2
1.7.4
=====
Fixes:
------
* Fix potential use after free if the `string` parameter to `cJSON_AddItemToObject` is an alias of the `string` property of the object that is added (#248). Thanks @hhallen for reporting.

1.7.3
=====
Fixes:
------
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ include(GNUInstallDirs)

set(PROJECT_VERSION_MAJOR 1)
set(PROJECT_VERSION_MINOR 7)
set(PROJECT_VERSION_PATCH 3)
set(PROJECT_VERSION_PATCH 4)
set(CJSON_VERSION_SO 1)
set(CJSON_UTILS_VERSION_SO 1)
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ CJSON_TEST_SRC = cJSON.c test.c

LDLIBS = -lm

LIBVERSION = 1.7.3
LIBVERSION = 1.7.4
CJSON_SOVERSION = 1
UTILS_SOVERSION = 1

Expand Down
29 changes: 17 additions & 12 deletions cJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) {
}

/* 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 != 3)
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 4)
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
#endif

Expand Down Expand Up @@ -1895,33 +1895,38 @@ static void* cast_away_const(const void* string)

static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
{
char *new_key = NULL;
int new_type = cJSON_Invalid;

if ((object == NULL) || (string == NULL) || (item == NULL))
{
return false;
}

if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
{
hooks->deallocate(item->string);
}

if (constant_key)
{
item->string = (char*)cast_away_const(string);
item->type |= cJSON_StringIsConst;
new_key = (char*)cast_away_const(string);
new_type = item->type | cJSON_StringIsConst;
}
else
{
char *key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
if (key == NULL)
new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
if (new_key == NULL)
{
return false;
}

item->string = key;
item->type &= ~cJSON_StringIsConst;
new_type = item->type & ~cJSON_StringIsConst;
}

if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
{
hooks->deallocate(item->string);
}

item->string = new_key;
item->type = new_type;

return add_item_to_array(object, item);
}

Expand Down
2 changes: 1 addition & 1 deletion cJSON.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extern "C"
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 3
#define CJSON_VERSION_PATCH 4

#include <stddef.h>

Expand Down
20 changes: 20 additions & 0 deletions tests/misc_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,25 @@ static void cjson_create_array_reference_should_create_an_array_reference(void)
cJSON_Delete(number_reference);
}

static void cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased(void)
{
cJSON *object = cJSON_CreateObject();
cJSON *number = cJSON_CreateNumber(42);
char *name = (char*)cJSON_strdup((const unsigned char*)"number", &global_hooks);

TEST_ASSERT_NOT_NULL(object);
TEST_ASSERT_NOT_NULL(number);
TEST_ASSERT_NOT_NULL(name);

number->string = name;

/* The following should not have a use after free
* that would show up in valgrind or with AddressSanitizer */
cJSON_AddItemToObject(object, number->string, number);

cJSON_Delete(object);
}

int main(void)
{
UNITY_BEGIN();
Expand All @@ -530,6 +549,7 @@ int main(void)
RUN_TEST(cjson_create_string_reference_should_create_a_string_reference);
RUN_TEST(cjson_create_object_reference_should_create_an_object_reference);
RUN_TEST(cjson_create_array_reference_should_create_an_array_reference);
RUN_TEST(cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased);

return UNITY_END();
}

0 comments on commit 6f264b5

Please sign in to comment.