Browse Source

Make frozen tolerate 0x.. numbers

CL: Make frozen tolerate 0x.. numbers

PUBLISHED_FROM=1b362d938c44cfeda952b32c140f2c885f023697
Бобби 7 years ago
parent
commit
a6f91b4dc3
2 changed files with 30 additions and 12 deletions
  1. 19 12
      frozen.c
  2. 11 0
      unit_test.c

+ 19 - 12
frozen.c

@@ -259,21 +259,28 @@ static int parse_number(struct frozen *f) {
   SET_STATE(f, f->cur, "", 0);
   if (ch == '-') f->cur++;
   EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
-  EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
-  while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
-  if (f->cur < f->end && f->cur[0] == '.') {
-    f->cur++;
-    EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
-    EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
-    while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
-  }
-  if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) {
-    f->cur++;
-    EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
-    if ((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++;
+  if (f->cur + 1 < f->end && f->cur[0] == '0' && f->cur[1] == 'x') {
+    f->cur += 2;
     EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
+    EXPECT(is_hex_digit(f->cur[0]), JSON_STRING_INVALID);
+    while (f->cur < f->end && is_hex_digit(f->cur[0])) f->cur++;
+  } else {
     EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
     while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
+    if (f->cur < f->end && f->cur[0] == '.') {
+      f->cur++;
+      EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
+      EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
+      while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
+    }
+    if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) {
+      f->cur++;
+      EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
+      if ((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++;
+      EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
+      EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID);
+      while (f->cur < f->end && is_digit(f->cur[0])) f->cur++;
+    }
   }
   truncate_path(f, fstate.path_len);
   CALL_BACK(f, JSON_TYPE_NUMBER, fstate.ptr, f->cur - fstate.ptr);

+ 11 - 0
unit_test.c

@@ -644,6 +644,17 @@ static const char *test_scanf(void) {
     ASSERT(fabs(fc - c) < FLT_EPSILON);
   }
 
+  {
+    int v = -1;
+    ASSERT(json_scanf("0x", 2, "%i", &v) == 0); // Incomplete string
+    ASSERT(json_scanf("0xe", 3, "%i", &v) == 1);
+    ASSERT(v == 14);
+    ASSERT(json_scanf("0x12", 4, "%i", &v) == 1);
+    ASSERT(v == 18);
+    ASSERT(json_scanf("12", 2, "%i", &v) == 1);
+    ASSERT(v == 12);
+  }
+
   return NULL;
 }