]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
Eliminate use of ctype.h and replace isdigit() and tolower() with non-locale-sensitiv...
authorEric Haszlakiewicz <erh+git@nimenees.com>
Sun, 2 Aug 2020 04:06:44 +0000 (04:06 +0000)
committerEric Haszlakiewicz <erh+git@nimenees.com>
Sun, 2 Aug 2020 04:06:44 +0000 (04:06 +0000)
json_object.c
json_pointer.c
json_tokener.c
json_util.c

index a8ca72208ac00d0c2f0f4d923e3f875139985002..a555da5df0c4ceb1cadee5f13766b1eb5c6dfd8e 100644 (file)
@@ -13,7 +13,6 @@
 #include "strerror_override.h"
 
 #include <assert.h>
-#include <ctype.h>
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #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 */
index 99cc54283cda3fbf329bbd08ee02ae6ddaf5d631..395567a5ba6c1ef48d4d212e8bb491f394ed75ec 100644 (file)
@@ -10,7 +10,6 @@
 
 #include "strerror_override.h"
 
-#include <ctype.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -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;
index 4722621d191050c2214f0918a781f16b0998112e..e16db6b88414468bc0642f7b064a4b55c79c5bd0 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "math_compat.h"
 #include <assert.h>
-#include <ctype.h>
 #include <limits.h>
 #include <math.h>
 #include <stddef.h>
@@ -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;
index a0655234b7d234c12bffae30ba6be98bdd231aad..4312458c58f5bfb50a8084f303b9b2624b93f641 100644 (file)
@@ -14,7 +14,6 @@
 
 #include "strerror_override.h"
 
-#include <ctype.h>
 #include <limits.h>
 #include <stdarg.h>
 #include <stddef.h>