]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
reject leading zeros in strict-mode number parsing 953/head
authorJavid Khan <dxbjavid@gmail.com>
Tue, 28 Jul 2026 07:57:25 +0000 (13:27 +0530)
committerJavid Khan <dxbjavid@gmail.com>
Tue, 28 Jul 2026 07:57:25 +0000 (13:27 +0530)
json_tokener.c
tests/test_parse.c
tests/test_parse.expected

index 1b44ec5d372ef9e05207af0ddbc0de631d25607a..b723f139b2ee94eb62178ff5b2963a1fa4e06d77 100644 (file)
@@ -1043,6 +1043,22 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
                                tok->st_pos = 0;
                                goto redo_char;
                        }
+                       if (tok->flags & JSON_TOKENER_STRICT)
+                       {
+                               /* RFC 8259 forbids leading zeros in the integer part:
+                                * a '0' may only be followed by '.', 'e'/'E' or the end
+                                * of the number, so "01", "00" and "-0123" are invalid
+                                * while "0", "-0" and "0.5" remain valid.
+                                */
+                               const char *num = tok->pb->buf;
+                               if (*num == '-')
+                                       num++;
+                               if (num[0] == '0' && num[1] >= '0' && num[1] <= '9')
+                               {
+                                       tok->err = json_tokener_error_parse_number;
+                                       goto out;
+                               }
+                       }
                        if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
                        {
                                /* Trim some chars off the end, to allow things
@@ -1087,12 +1103,6 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
                                                tok->err = json_tokener_error_parse_number;
                                                goto out;
                                        }
-                                       if (numuint64 && tok->pb->buf[0] == '0' &&
-                                           (tok->flags & JSON_TOKENER_STRICT))
-                                       {
-                                               tok->err = json_tokener_error_parse_number;
-                                               goto out;
-                                       }
                                        if (numuint64 <= INT64_MAX)
                                        {
                                                num64 = (uint64_t)numuint64;
index 9bcf278cb585d0d6a7f7230ae7ce103ddd7e12bb..897863af41bee11b3c60a05596a650ec6d0f3f92 100644 (file)
@@ -366,6 +366,15 @@ struct incremental_step
     {"12{", 3, 2, json_tokener_success, 1, 0},
     /* Parse number in strict mode */
     {"[02]", -1, 3, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
+    /* Leading zeros are rejected in strict mode, for every sign and type ... */
+    {"[00]", -1, 3, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
+    {"[-00]", -1, 4, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
+    {"[-01]", -1, 4, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
+    {"[-0123]", -1, 6, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
+    {"[01.5]", -1, 5, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
+    /* ... but a lone zero, "-0" and a zero before the fraction stay valid. */
+    {"[-0]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
+    {"[0.5]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
 
     {"0e+0", 5, 4, json_tokener_success, 1, 0},
     {"[0e+0]", -1, -1, json_tokener_success, 1, 0},
index 8d3961f51d6dae24262a2d70a4f8af759dad3fa5..acf0594d1105ee73e4f7653c44e863d8471b0c88 100644 (file)
@@ -156,6 +156,13 @@ json_tokener_parse_ex(tok, 1           ,   1) ... OK: got correct error: continu
 json_tokener_parse_ex(tok, 2           ,   2) ... OK: got object of type [int]: 12
 json_tokener_parse_ex(tok, 12{         ,   3) ... OK: got object of type [int]: 12
 json_tokener_parse_ex(tok, [02]        ,   4) ... OK: got correct error: number expected
+json_tokener_parse_ex(tok, [00]        ,   4) ... OK: got correct error: number expected
+json_tokener_parse_ex(tok, [-00]       ,   5) ... OK: got correct error: number expected
+json_tokener_parse_ex(tok, [-01]       ,   5) ... OK: got correct error: number expected
+json_tokener_parse_ex(tok, [-0123]     ,   7) ... OK: got correct error: number expected
+json_tokener_parse_ex(tok, [01.5]      ,   6) ... OK: got correct error: number expected
+json_tokener_parse_ex(tok, [-0]        ,   4) ... OK: got object of type [array]: [ 0 ]
+json_tokener_parse_ex(tok, [0.5]       ,   5) ... OK: got object of type [array]: [ 0.5 ]
 json_tokener_parse_ex(tok, 0e+0        ,   5) ... OK: got object of type [double]: 0e+0
 json_tokener_parse_ex(tok, [0e+0]      ,   6) ... OK: got object of type [array]: [ 0e+0 ]
 json_tokener_parse_ex(tok, 0e          ,   2) ... OK: got correct error: continue
@@ -368,5 +375,5 @@ json_tokener_parse_ex(tok, {"\1c":1}     ,   7) ... OK: got correct error: invalid
 json_tokener_parse_ex(tok, {"\1d":1}     ,   7) ... OK: got correct error: invalid string sequence
 json_tokener_parse_ex(tok, {"\1e":1}     ,   7) ... OK: got correct error: invalid string sequence
 json_tokener_parse_ex(tok, {"\1f":1}     ,   7) ... OK: got correct error: invalid string sequence
-End Incremental Tests OK=272 ERROR=0
+End Incremental Tests OK=279 ERROR=0
 ==================================