diff --git a/cJSON.c b/cJSON.c index 524ba46..962ca22 100644 --- a/cJSON.c +++ b/cJSON.c @@ -124,7 +124,7 @@ CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) CJSON_PUBLIC(const char*) cJSON_Version(void) { static char version[15]; - sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); + snprintf(version, sizeof(version), "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); return version; } @@ -560,26 +560,26 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out /* This checks for NaN and Infinity */ if (isnan(d) || isinf(d)) { - length = sprintf((char*)number_buffer, "null"); + length = snprintf((char*)number_buffer, sizeof(number_buffer), "null"); } else if(d == (double)item->valueint) { - length = sprintf((char*)number_buffer, "%d", item->valueint); + length = snprintf((char*)number_buffer, sizeof(number_buffer), "%d", item->valueint); } else { /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ - length = sprintf((char*)number_buffer, "%1.15g", d); + length = snprintf((char*)number_buffer, sizeof(number_buffer), "%1.15g", d); /* Check whether the original double can be recovered */ if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) { /* If not, print with 17 decimal places of precision */ - length = sprintf((char*)number_buffer, "%1.17g", d); + length = snprintf((char*)number_buffer, sizeof(number_buffer), "%1.17g", d); } } - /* sprintf failed or buffer overrun occurred */ + /* snprintf failed or buffer overrun occurred */ if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) { return false; @@ -952,7 +952,8 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe } output_length = (size_t)(input_pointer - input) + escape_characters; - output = ensure(output_buffer, output_length + sizeof("\"\"")); + size_t size = output_length + sizeof("\"\""); + output = ensure(output_buffer, size); if (output == NULL) { return false; @@ -1008,7 +1009,8 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe break; default: /* escape and print as unicode codepoint */ - sprintf((char*)output_pointer, "u%04x", *input_pointer); + snprintf((char*)output_pointer, size - 1, "u%04x", *input_pointer); + output_pointer += 4; break; } diff --git a/cJSON_Utils.c b/cJSON_Utils.c index 63651df..54e4031 100644 --- a/cJSON_Utils.c +++ b/cJSON_Utils.c @@ -221,7 +221,8 @@ CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const obje if (cJSON_IsArray(object)) { /* reserve enough memory for a 64 bit integer + '/' and '\0' */ - unsigned char *full_pointer = (unsigned char*)cJSON_malloc(strlen((char*)target_pointer) + 20 + sizeof("/")); + size_t size = strlen((char*)target_pointer) + 20 + sizeof("/"); + unsigned char *full_pointer = (unsigned char*)cJSON_malloc(size); /* check if conversion to unsigned long is valid * This should be eliminated at compile time by dead code elimination * if size_t is an alias of unsigned long, or if it is bigger */ @@ -231,7 +232,7 @@ CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const obje cJSON_free(full_pointer); return NULL; } - sprintf((char*)full_pointer, "/%lu%s", (unsigned long)child_index, target_pointer); /* / */ + snprintf((char*)full_pointer, size, "/%lu%s", (unsigned long)child_index, target_pointer); /* / */ cJSON_free(target_pointer); return (char*)full_pointer; @@ -1117,9 +1118,10 @@ static void compose_patch(cJSON * const patches, const unsigned char * const ope { size_t suffix_length = pointer_encoded_length(suffix); size_t path_length = strlen((const char*)path); - unsigned char *full_path = (unsigned char*)cJSON_malloc(path_length + suffix_length + sizeof("/")); + size_t size = path_length + suffix_length + sizeof("/"); + unsigned char *full_path = (unsigned char*)cJSON_malloc(size); - sprintf((char*)full_path, "%s/", (const char*)path); + snprintf((char*)full_path, size, "%s/", (const char*)path); encode_string_as_pointer(full_path + path_length + 1, suffix); cJSON_AddItemToObject(patch, "path", cJSON_CreateString((const char*)full_path)); @@ -1172,7 +1174,8 @@ static void create_patches(cJSON * const patches, const unsigned char * const pa size_t index = 0; cJSON *from_child = from->child; cJSON *to_child = to->child; - unsigned char *new_path = (unsigned char*)cJSON_malloc(strlen((const char*)path) + 20 + sizeof("/")); /* Allow space for 64bit int. log10(2^64) = 20 */ + size_t size = strlen((const char*)path) + 20 + sizeof("/"); /* Allow space for 64bit int. log10(2^64) = 20 */ + unsigned char *new_path = (unsigned char*)cJSON_malloc(size); /* generate patches for all array elements that exist in both "from" and "to" */ for (index = 0; (from_child != NULL) && (to_child != NULL); (void)(from_child = from_child->next), (void)(to_child = to_child->next), index++) @@ -1185,7 +1188,7 @@ static void create_patches(cJSON * const patches, const unsigned char * const pa cJSON_free(new_path); return; } - sprintf((char*)new_path, "%s/%lu", path, (unsigned long)index); /* path of the current array element */ + snprintf((char*)new_path, size, "%s/%lu", path, (unsigned long)index); /* path of the current array element */ create_patches(patches, new_path, from_child, to_child, case_sensitive); } @@ -1200,7 +1203,7 @@ static void create_patches(cJSON * const patches, const unsigned char * const pa cJSON_free(new_path); return; } - sprintf((char*)new_path, "%lu", (unsigned long)index); + snprintf((char*)new_path, size, "%lu", (unsigned long)index); compose_patch(patches, (const unsigned char*)"remove", path, new_path, NULL); } /* add new elements in 'to' that were not in 'from' */ @@ -1243,9 +1246,10 @@ static void create_patches(cJSON * const patches, const unsigned char * const pa /* both object keys are the same */ size_t path_length = strlen((const char*)path); size_t from_child_name_length = pointer_encoded_length((unsigned char*)from_child->string); - unsigned char *new_path = (unsigned char*)cJSON_malloc(path_length + from_child_name_length + sizeof("/")); + size_t size = path_length + from_child_name_length + sizeof("/"); + unsigned char *new_path = (unsigned char*)cJSON_malloc(size); - sprintf((char*)new_path, "%s/", path); + snprintf((char*)new_path, size, "%s/", path); encode_string_as_pointer(new_path + path_length + 1, (unsigned char*)from_child->string); /* create a patch for the element */ diff --git a/tests/parse_examples.c b/tests/parse_examples.c index 95a0959..f8c6bc3 100644 --- a/tests/parse_examples.c +++ b/tests/parse_examples.c @@ -59,14 +59,16 @@ static void do_test(const char *test_name) /* allocate file paths */ #define TEST_DIR_PATH "inputs/" - test_path = (char*)malloc(sizeof(TEST_DIR_PATH) + test_name_length); + size_t test_path_size = sizeof(TEST_DIR_PATH) + test_name_length; + test_path = (char*)malloc(test_path_size); TEST_ASSERT_NOT_NULL_MESSAGE(test_path, "Failed to allocate test_path buffer."); - expected_path = (char*)malloc(sizeof(TEST_DIR_PATH) + test_name_length + sizeof(".expected")); + size_t expected_path_size = sizeof(TEST_DIR_PATH) + test_name_length + sizeof(".expected"); + expected_path = (char*)malloc(expected_path_size); TEST_ASSERT_NOT_NULL_MESSAGE(expected_path, "Failed to allocate expected_path buffer."); /* create file paths */ - sprintf(test_path, TEST_DIR_PATH"%s", test_name); - sprintf(expected_path, TEST_DIR_PATH"%s.expected", test_name); + snprintf(test_path, test_path_size, TEST_DIR_PATH"%s", test_name); + snprintf(expected_path, expected_path_size, TEST_DIR_PATH"%s.expected", test_name); /* read expected output */ expected = read_file(expected_path); diff --git a/tests/parse_hex4.c b/tests/parse_hex4.c index 83cbe65..4d2872f 100644 --- a/tests/parse_hex4.c +++ b/tests/parse_hex4.c @@ -36,8 +36,8 @@ static void parse_hex4_should_parse_all_combinations(void) /* test all combinations */ for (number = 0; number <= 0xFFFF; number++) { - TEST_ASSERT_EQUAL_INT_MESSAGE(4, sprintf((char*)digits_lower, "%.4x", number), "sprintf failed."); - TEST_ASSERT_EQUAL_INT_MESSAGE(4, sprintf((char*)digits_upper, "%.4X", number), "sprintf failed."); + TEST_ASSERT_EQUAL_INT_MESSAGE(4, snprintf((char*)digits_lower, sizeof(digits_lower), "%.4x", number), "snprintf failed."); + TEST_ASSERT_EQUAL_INT_MESSAGE(4, snprintf((char*)digits_upper, sizeof(digits_upper), "%.4X", number), "snprintf failed."); TEST_ASSERT_EQUAL_INT_MESSAGE(number, parse_hex4(digits_lower), "Failed to parse lowercase digits."); TEST_ASSERT_EQUAL_INT_MESSAGE(number, parse_hex4(digits_upper), "Failed to parse uppercase digits.");