Skip to content

Commit 8c7849e

Browse files
committed
Eliminate use of ctype.h and replace isdigit() and tolower() with non-locale-sensitive approaches.
1 parent f3d8006 commit 8c7849e

File tree

4 files changed

+16
-15
lines changed

4 files changed

+16
-15
lines changed

json_object.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "strerror_override.h"
1414

1515
#include <assert.h>
16-
#include <ctype.h>
1716
#ifdef HAVE_LIMITS_H
1817
#include <limits.h>
1918
#endif
@@ -35,6 +34,9 @@
3534
#include "snprintf_compat.h"
3635
#include "strdup_compat.h"
3736

37+
/* Avoid ctype.h and locale overhead */
38+
#define is_plain_digit(c) ((c) >= '0' && (c) <= '9')
39+
3840
#if SIZEOF_LONG_LONG != SIZEOF_INT64_T
3941
#error "The long long type isn't 64-bits"
4042
#endif
@@ -1056,8 +1058,8 @@ static int json_object_double_to_json_string_format(struct json_object *jso, str
10561058
format_drops_decimals = 1;
10571059

10581060
looks_numeric = /* Looks like *some* kind of number */
1059-
isdigit((unsigned char)buf[0]) ||
1060-
(size > 1 && buf[0] == '-' && isdigit((unsigned char)buf[1]));
1061+
is_plain_digit(buf[0]) ||
1062+
(size > 1 && buf[0] == '-' && is_plain_digit(buf[1]));
10611063

10621064
if (size < (int)sizeof(buf) - 2 && looks_numeric && !p && /* Has no decimal point */
10631065
strchr(buf, 'e') == NULL && /* Not scientific notation */

json_pointer.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
#include "strerror_override.h"
1212

13-
#include <ctype.h>
1413
#include <stdarg.h>
1514
#include <stdio.h>
1615
#include <stdlib.h>
@@ -20,6 +19,9 @@
2019
#include "strdup_compat.h"
2120
#include "vasprintf_compat.h"
2221

22+
/* Avoid ctype.h and locale overhead */
23+
#define is_plain_digit(c) ((c) >= '0' && (c) <= '9')
24+
2325
/**
2426
* JavaScript Object Notation (JSON) Pointer
2527
* 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
4749
*/
4850
if (len == 1)
4951
{
50-
if (isdigit((unsigned char)path[0]))
52+
if (is_plain_digit(path[0]))
5153
{
5254
*idx = (path[0] - '0');
5355
goto check_oob;
@@ -64,7 +66,7 @@ static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx
6466
/* RFC states base-10 decimals */
6567
for (i = 0; i < len; i++)
6668
{
67-
if (!isdigit((unsigned char)path[i]))
69+
if (!is_plain_digit(path[i]))
6870
{
6971
errno = EINVAL;
7072
return 0;

json_tokener.c

+6-8
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
#include "math_compat.h"
1919
#include <assert.h>
20-
#include <ctype.h>
2120
#include <limits.h>
2221
#include <math.h>
2322
#include <stddef.h>
@@ -82,7 +81,8 @@ static inline int is_hex_char(char c)
8281
static const char json_null_str[] = "null";
8382
static const int json_null_str_len = sizeof(json_null_str) - 1;
8483
static const char json_inf_str[] = "Infinity";
85-
static const char json_inf_str_lower[] = "infinity";
84+
/* Swapped case "Infinity" to avoid need to call tolower() on input chars: */
85+
static const char json_inf_str_invert[] = "iNFINITY";
8686
static const unsigned int json_inf_str_len = sizeof(json_inf_str) - 1;
8787
static const char json_nan_str[] = "NaN";
8888
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 *
442442
* complicated with likely little performance benefit.
443443
*/
444444
int is_negative = 0;
445-
const char *_json_inf_str = json_inf_str;
446-
if (!(tok->flags & JSON_TOKENER_STRICT))
447-
_json_inf_str = json_inf_str_lower;
448445

449446
/* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
450447
while (tok->st_pos < (int)json_inf_str_len)
451448
{
452449
char inf_char = *str;
453-
if (!(tok->flags & JSON_TOKENER_STRICT))
454-
inf_char = tolower((unsigned char)*str);
455-
if (inf_char != _json_inf_str[tok->st_pos])
450+
if (inf_char != json_inf_str[tok->st_pos] &&
451+
((tok->flags & JSON_TOKENER_STRICT) ||
452+
inf_char != json_inf_str_invert[tok->st_pos])
453+
)
456454
{
457455
tok->err = json_tokener_error_parse_unexpected;
458456
goto out;

json_util.c

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
#include "strerror_override.h"
1616

17-
#include <ctype.h>
1817
#include <limits.h>
1918
#include <stdarg.h>
2019
#include <stddef.h>

0 commit comments

Comments
 (0)