From: Eric Haszlakiewicz Date: Sun, 2 Aug 2020 04:06:44 +0000 (+0000) Subject: Eliminate use of ctype.h and replace isdigit() and tolower() with non-locale-sensitiv... X-Git-Tag: json-c-0.16-20220414~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8c7849e6e3b985825be770041af2b948fa6d8918;p=thirdparty%2Fjson-c.git Eliminate use of ctype.h and replace isdigit() and tolower() with non-locale-sensitive approaches. --- diff --git a/json_object.c b/json_object.c index a8ca7220..a555da5d 100644 --- a/json_object.c +++ b/json_object.c @@ -13,7 +13,6 @@ #include "strerror_override.h" #include -#include #ifdef HAVE_LIMITS_H #include #endif @@ -35,6 +34,9 @@ #include "snprintf_compat.h" #include "strdup_compat.h" +/* Avoid ctype.h and locale overhead */ +#define is_plain_digit(c) ((c) >= '0' && (c) <= '9') + #if SIZEOF_LONG_LONG != SIZEOF_INT64_T #error "The long long type isn't 64-bits" #endif @@ -1056,8 +1058,8 @@ static int json_object_double_to_json_string_format(struct json_object *jso, str format_drops_decimals = 1; looks_numeric = /* Looks like *some* kind of number */ - isdigit((unsigned char)buf[0]) || - (size > 1 && buf[0] == '-' && isdigit((unsigned char)buf[1])); + is_plain_digit(buf[0]) || + (size > 1 && buf[0] == '-' && is_plain_digit(buf[1])); if (size < (int)sizeof(buf) - 2 && looks_numeric && !p && /* Has no decimal point */ strchr(buf, 'e') == NULL && /* Not scientific notation */ diff --git a/json_pointer.c b/json_pointer.c index 99cc5428..395567a5 100644 --- a/json_pointer.c +++ b/json_pointer.c @@ -10,7 +10,6 @@ #include "strerror_override.h" -#include #include #include #include @@ -20,6 +19,9 @@ #include "strdup_compat.h" #include "vasprintf_compat.h" +/* Avoid ctype.h and locale overhead */ +#define is_plain_digit(c) ((c) >= '0' && (c) <= '9') + /** * JavaScript Object Notation (JSON) Pointer * RFC 6901 - https://tools.ietf.org/html/rfc6901 @@ -47,7 +49,7 @@ static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx */ if (len == 1) { - if (isdigit((unsigned char)path[0])) + if (is_plain_digit(path[0])) { *idx = (path[0] - '0'); goto check_oob; @@ -64,7 +66,7 @@ static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx /* RFC states base-10 decimals */ for (i = 0; i < len; i++) { - if (!isdigit((unsigned char)path[i])) + if (!is_plain_digit(path[i])) { errno = EINVAL; return 0; diff --git a/json_tokener.c b/json_tokener.c index 4722621d..e16db6b8 100644 --- a/json_tokener.c +++ b/json_tokener.c @@ -17,7 +17,6 @@ #include "math_compat.h" #include -#include #include #include #include @@ -82,7 +81,8 @@ static inline int is_hex_char(char c) static const char json_null_str[] = "null"; static const int json_null_str_len = sizeof(json_null_str) - 1; static const char json_inf_str[] = "Infinity"; -static const char json_inf_str_lower[] = "infinity"; +/* Swapped case "Infinity" to avoid need to call tolower() on input chars: */ +static const char json_inf_str_invert[] = "iNFINITY"; static const unsigned int json_inf_str_len = sizeof(json_inf_str) - 1; static const char json_nan_str[] = "NaN"; static const int json_nan_str_len = sizeof(json_nan_str) - 1; @@ -442,17 +442,15 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * * complicated with likely little performance benefit. */ int is_negative = 0; - const char *_json_inf_str = json_inf_str; - if (!(tok->flags & JSON_TOKENER_STRICT)) - _json_inf_str = json_inf_str_lower; /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */ while (tok->st_pos < (int)json_inf_str_len) { char inf_char = *str; - if (!(tok->flags & JSON_TOKENER_STRICT)) - inf_char = tolower((unsigned char)*str); - if (inf_char != _json_inf_str[tok->st_pos]) + if (inf_char != json_inf_str[tok->st_pos] && + ((tok->flags & JSON_TOKENER_STRICT) || + inf_char != json_inf_str_invert[tok->st_pos]) + ) { tok->err = json_tokener_error_parse_unexpected; goto out; diff --git a/json_util.c b/json_util.c index a0655234..4312458c 100644 --- a/json_util.c +++ b/json_util.c @@ -14,7 +14,6 @@ #include "strerror_override.h" -#include #include #include #include