Browse Source

Eliminate use of ctype.h and replace isdigit() and tolower() with non-locale-sensitive approaches.

tags/json-c-0.16-20220414
Eric Haszlakiewicz 5 years ago
parent
commit
8c7849e6e3
4 changed files with 16 additions and 15 deletions
  1. +5
    -3
      json_object.c
  2. +5
    -3
      json_pointer.c
  3. +6
    -8
      json_tokener.c
  4. +0
    -1
      json_util.c

+ 5
- 3
json_object.c View File

@@ -13,7 +13,6 @@
#include "strerror_override.h" #include "strerror_override.h"


#include <assert.h> #include <assert.h>
#include <ctype.h>
#ifdef HAVE_LIMITS_H #ifdef HAVE_LIMITS_H
#include <limits.h> #include <limits.h>
#endif #endif
@@ -35,6 +34,9 @@
#include "snprintf_compat.h" #include "snprintf_compat.h"
#include "strdup_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 #if SIZEOF_LONG_LONG != SIZEOF_INT64_T
#error "The long long type isn't 64-bits" #error "The long long type isn't 64-bits"
#endif #endif
@@ -1056,8 +1058,8 @@ static int json_object_double_to_json_string_format(struct json_object *jso, str
format_drops_decimals = 1; format_drops_decimals = 1;


looks_numeric = /* Looks like *some* kind of number */ 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 */ if (size < (int)sizeof(buf) - 2 && looks_numeric && !p && /* Has no decimal point */
strchr(buf, 'e') == NULL && /* Not scientific notation */ strchr(buf, 'e') == NULL && /* Not scientific notation */


+ 5
- 3
json_pointer.c View File

@@ -10,7 +10,6 @@


#include "strerror_override.h" #include "strerror_override.h"


#include <ctype.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -20,6 +19,9 @@
#include "strdup_compat.h" #include "strdup_compat.h"
#include "vasprintf_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 * JavaScript Object Notation (JSON) Pointer
* RFC 6901 - https://tools.ietf.org/html/rfc6901 * 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 (len == 1)
{ {
if (isdigit((unsigned char)path[0]))
if (is_plain_digit(path[0]))
{ {
*idx = (path[0] - '0'); *idx = (path[0] - '0');
goto check_oob; 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 */ /* RFC states base-10 decimals */
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
if (!isdigit((unsigned char)path[i]))
if (!is_plain_digit(path[i]))
{ {
errno = EINVAL; errno = EINVAL;
return 0; return 0;


+ 6
- 8
json_tokener.c View File

@@ -17,7 +17,6 @@


#include "math_compat.h" #include "math_compat.h"
#include <assert.h> #include <assert.h>
#include <ctype.h>
#include <limits.h> #include <limits.h>
#include <math.h> #include <math.h>
#include <stddef.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 char json_null_str[] = "null";
static const int json_null_str_len = sizeof(json_null_str) - 1; 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[] = "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 unsigned int json_inf_str_len = sizeof(json_inf_str) - 1;
static const char json_nan_str[] = "NaN"; static const char json_nan_str[] = "NaN";
static const int json_nan_str_len = sizeof(json_nan_str) - 1; 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. * complicated with likely little performance benefit.
*/ */
int is_negative = 0; 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 */ /* 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) while (tok->st_pos < (int)json_inf_str_len)
{ {
char inf_char = *str; 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; tok->err = json_tokener_error_parse_unexpected;
goto out; goto out;


+ 0
- 1
json_util.c View File

@@ -14,7 +14,6 @@


#include "strerror_override.h" #include "strerror_override.h"


#include <ctype.h>
#include <limits.h> #include <limits.h>
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> #include <stddef.h>


Loading…
Cancel
Save