From 15d9ec8b0745fbcc9f112bc438fffa368daa4f0b Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Wed, 10 Jan 2018 17:43:25 +0100 Subject: [PATCH] New macro static_strlen and replace magic numbers with it. --- cJSON.c | 77 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/cJSON.c b/cJSON.c index 1b08b3d..1fbd17f 100644 --- a/cJSON.c +++ b/cJSON.c @@ -145,6 +145,9 @@ static void *internal_realloc(void *pointer, size_t size) #define internal_realloc realloc #endif +/* Compile time strlen for string literals */ +#define static_strlen(literal) ((size_t)(sizeof(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) @@ -280,7 +283,7 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu /* 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 */ - for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) + for (i = 0; (i < (sizeof(number_c_string) - sizeof(""))) && can_access_at_index(input_buffer, i); i++) { switch (buffer_at_offset(input_buffer)[i]) { @@ -506,7 +509,7 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out } /* sprintf failed or buffer overrun occured */ - if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) + if ((length < 0) || (length > (int)(sizeof(number_buffer) - sizeof("")))) { return false; } @@ -585,14 +588,14 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi unsigned char sequence_length = 0; unsigned char first_byte_mark = 0; - if ((input_end - first_sequence) < 6) + if ((input_end - first_sequence) < ((int)static_strlen("\\uXXXX"))) { /* input ends unexpectedly */ goto fail; } /* get the first utf16 sequence */ - first_code = parse_hex4(first_sequence + 2); + first_code = parse_hex4(first_sequence + static_strlen("\\u")); /* check that the code is valid */ if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) @@ -603,11 +606,11 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi /* UTF16 surrogate pair */ if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) { - const unsigned char *second_sequence = first_sequence + 6; + const unsigned char *second_sequence = first_sequence + static_strlen("\\uXXXX"); unsigned int second_code = 0; - sequence_length = 12; /* \uXXXX\uXXXX */ + sequence_length = static_strlen("\\uXXXX\\uXXXX"); - if ((input_end - second_sequence) < 6) + if ((input_end - second_sequence) < ((int)static_strlen("\\uXXXX"))) { /* input ends unexpectedly */ goto fail; @@ -620,7 +623,7 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi } /* get the second utf16 sequence */ - second_code = parse_hex4(second_sequence + 2); + second_code = parse_hex4(second_sequence + static_strlen("\\u")); /* check that the code is valid */ if ((second_code < 0xDC00) || (second_code > 0xDFFF)) { @@ -634,7 +637,7 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi } else { - sequence_length = 6; /* \uXXXX */ + sequence_length = static_strlen("\\uXXXX"); codepoint = first_code; } @@ -698,8 +701,8 @@ fail: /* Parse the input text into an unescaped cinput, and populate item. */ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) { - const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; - const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; + const unsigned char *input_pointer = buffer_at_offset(input_buffer) + static_strlen("\""); + const unsigned char *input_end = buffer_at_offset(input_buffer) + static_strlen("\""); unsigned char *output_pointer = NULL; unsigned char *output = NULL; @@ -718,7 +721,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu /* is escape sequence */ if (input_end[0] == '\\') { - if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) + if ((size_t)(input_end + sizeof("") - input_buffer->content) >= input_buffer->length) { /* prevent buffer overflow when last input character is a backslash */ goto fail; @@ -753,7 +756,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu /* escape sequence */ else { - unsigned char sequence_length = 2; + unsigned char sequence_length = static_strlen("\\X"); if ((input_end - input_pointer) < 1) { goto fail; @@ -870,8 +873,8 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe default: if (*input_pointer < 32) { - /* UTF-16 escape sequence uXXXX */ - escape_characters += 5; + /* UTF-16 escape sequence */ + escape_characters += static_strlen("uXXXX"); } break; } @@ -888,7 +891,7 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe if (escape_characters == 0) { output[0] = '\"'; - memcpy(output + 1, input, output_length); + memcpy(output + static_strlen("\""), input, output_length); output[output_length + 1] = '\"'; output[output_length + 2] = '\0'; @@ -896,7 +899,7 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe } output[0] = '\"'; - output_pointer = output + 1; + output_pointer = output + static_strlen("\""); /* copy the string */ for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) { @@ -935,7 +938,7 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe default: /* escape and print as unicode codepoint */ sprintf((char*)output_pointer, "u%04x", *input_pointer); - output_pointer += 4; + output_pointer += static_strlen("XXXX"); break; } } @@ -989,9 +992,9 @@ static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) return NULL; } - if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) + if (can_access_at_index(buffer, sizeof("\xEF\xBB\xBF")) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", static_strlen("\xEF\xBB\xBF")) == 0)) { - buffer->offset += 3; + buffer->offset += static_strlen("\xEF\xBB\xBF"); } return buffer; @@ -1219,25 +1222,25 @@ static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buf /* parse the different types of values */ /* null */ - if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) + if (can_read(input_buffer, static_strlen("null")) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", static_strlen("null")) == 0)) { item->type = cJSON_NULL; - input_buffer->offset += 4; + input_buffer->offset += static_strlen("null"); return true; } /* false */ - if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) + if (can_read(input_buffer, static_strlen("false")) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", static_strlen("false")) == 0)) { item->type = cJSON_False; - input_buffer->offset += 5; + input_buffer->offset += static_strlen("false"); return true; } /* true */ - if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) + if (can_read(input_buffer, static_strlen("true")) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", static_strlen("true")) == 0)) { item->type = cJSON_True; item->valueint = 1; - input_buffer->offset += 4; + input_buffer->offset += static_strlen("true"); return true; } /* string */ @@ -1450,7 +1453,7 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp /* Compose the output array. */ /* opening square bracket */ - output_pointer = ensure(output_buffer, 1); + output_pointer = ensure(output_buffer, static_strlen("[")); if (output_pointer == NULL) { return false; @@ -1469,8 +1472,8 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp update_offset(output_buffer); if (current_element->next) { - length = (size_t) (output_buffer->format ? 2 : 1); - output_pointer = ensure(output_buffer, length + 1); + length = (size_t) (output_buffer->format ? static_strlen(", ") : static_strlen(",")); + output_pointer = ensure(output_buffer, length + sizeof("")); if (output_pointer == NULL) { return false; @@ -1486,7 +1489,7 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp current_element = current_element->next; } - output_pointer = ensure(output_buffer, 2); + output_pointer = ensure(output_buffer, sizeof("]")); if (output_pointer == NULL) { return false; @@ -1620,8 +1623,8 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out } /* Compose the output: */ - length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ - output_pointer = ensure(output_buffer, length + 1); + length = (size_t) (output_buffer->format ? static_strlen("{\n") : static_strlen("{")); + output_pointer = ensure(output_buffer, length + sizeof("")); if (output_pointer == NULL) { return false; @@ -1659,7 +1662,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out } update_offset(output_buffer); - length = (size_t) (output_buffer->format ? 2 : 1); + length = (size_t) (output_buffer->format ? static_strlen(":\t") : static_strlen(":")); output_pointer = ensure(output_buffer, length); if (output_pointer == NULL) { @@ -1680,8 +1683,8 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out update_offset(output_buffer); /* print comma if not last */ - length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0)); - output_pointer = ensure(output_buffer, length + 1); + length = (size_t) ((output_buffer->format ? static_strlen(",") : static_strlen("")) + (current_item->next ? static_strlen(",") : static_strlen(""))); + output_pointer = ensure(output_buffer, length + sizeof("")); if (output_pointer == NULL) { return false; @@ -1701,7 +1704,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out current_item = current_item->next; } - output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); + output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth - 1 + sizeof("}")) : sizeof("}")); if (output_pointer == NULL) { return false; @@ -2669,7 +2672,7 @@ CJSON_PUBLIC(void) cJSON_Minify(char *json) { json++; } - json += 2; + json += static_strlen("*/"); } else if (*json == '\"') {