Skip to content

Commit 26e69ff

Browse files
committed
Fix a bug in schema minimum/maximum keywords for 64-bit integer
1 parent ecd8fa3 commit 26e69ff

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

include/rapidjson/schema.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,9 @@ class Schema {
11081108
if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64())
11091109
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
11101110
}
1111+
else if (minimum_.IsUint64()) {
1112+
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64()
1113+
}
11111114
else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
11121115
return false;
11131116
}
@@ -1117,6 +1120,8 @@ class Schema {
11171120
if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64())
11181121
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
11191122
}
1123+
else if (maximum_.IsUint64())
1124+
/* do nothing */; // i <= max(int64_t) < maximum_.GetUint64()
11201125
else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
11211126
return false;
11221127
}
@@ -1142,6 +1147,8 @@ class Schema {
11421147
if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64())
11431148
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
11441149
}
1150+
else if (minimum_.IsInt64())
1151+
/* do nothing */; // i >= 0 > minimum.Getint64()
11451152
else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
11461153
return false;
11471154
}
@@ -1151,6 +1158,8 @@ class Schema {
11511158
if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64())
11521159
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
11531160
}
1161+
else if (maximum_.IsInt64())
1162+
RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_
11541163
else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
11551164
return false;
11561165
}

test/unittest/schematest.cpp

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ TEST(SchemaValidator, Hasher) {
5151
TEST_HASHER("false", "null", false);
5252

5353
TEST_HASHER("1", "1", true);
54+
TEST_HASHER("2147483648", "2147483648", true); // 2^31 can only be fit in unsigned
55+
TEST_HASHER("-2147483649", "-2147483649", true); // -2^31 - 1 can only be fit in int64_t
56+
TEST_HASHER("2147483648", "2147483648", true); // 2^31 can only be fit in unsigned
57+
TEST_HASHER("4294967296", "4294967296", true); // 2^32 can only be fit in int64_t
5458
TEST_HASHER("1.5", "1.5", true);
5559
TEST_HASHER("1", "1.0", true);
5660
TEST_HASHER("1", "-1", false);
@@ -316,6 +320,10 @@ TEST(SchemaValidator, String) {
316320

317321
VALIDATE(s, "\"I'm a string\"", true);
318322
INVALIDATE(s, "42", "", "type", "");
323+
INVALIDATE(s, "2147483648", "", "type", ""); // 2^31 can only be fit in unsigned
324+
INVALIDATE(s, "-2147483649", "", "type", ""); // -2^31 - 1 can only be fit in int64_t
325+
INVALIDATE(s, "4294967296", "", "type", ""); // 2^32 can only be fit in int64_t
326+
INVALIDATE(s, "3.1415926", "", "type", "");
319327
}
320328

321329
TEST(SchemaValidator, String_LengthRange) {
@@ -340,6 +348,16 @@ TEST(SchemaValidator, String_Pattern) {
340348
INVALIDATE(s, "\"(888)555-1212 ext. 532\"", "", "pattern", "");
341349
INVALIDATE(s, "\"(800)FLOWERS\"", "", "pattern", "");
342350
}
351+
352+
TEST(SchemaValidator, String_Pattern_Invalid) {
353+
Document sd;
354+
sd.Parse("{\"type\":\"string\",\"pattern\":\"a{0}\"}"); // TODO: report regex is invalid somehow
355+
SchemaDocument s(sd);
356+
357+
VALIDATE(s, "\"\"", true);
358+
VALIDATE(s, "\"a\"", true);
359+
VALIDATE(s, "\"aa\"", true);
360+
}
343361
#endif
344362

345363
TEST(SchemaValidator, Integer) {
@@ -349,6 +367,10 @@ TEST(SchemaValidator, Integer) {
349367

350368
VALIDATE(s, "42", true);
351369
VALIDATE(s, "-1", true);
370+
VALIDATE(s, "2147483648", true); // 2^31 can only be fit in unsigned
371+
VALIDATE(s, "-2147483649", true); // -2^31 - 1 can only be fit in int64_t
372+
VALIDATE(s, "2147483648", true); // 2^31 can only be fit in unsigned
373+
VALIDATE(s, "4294967296", true); // 2^32 can only be fit in int64_t
352374
INVALIDATE(s, "3.1415926", "", "type", "");
353375
INVALIDATE(s, "\"42\"", "", "type", "");
354376
}
@@ -368,11 +390,34 @@ TEST(SchemaValidator, Integer_Range) {
368390

369391
TEST(SchemaValidator, Integer_Range64Boundary) {
370392
Document sd;
371-
sd.Parse("{\"type\":\"integer\",\"minimum\":-9223372036854775807,\"maximum\":18446744073709551614}");
393+
sd.Parse("{\"type\":\"integer\",\"minimum\":-9223372036854775807,\"maximum\":9223372036854775806}");
372394
SchemaDocument s(sd);
373395

374396
INVALIDATE(s, "-9223372036854775808", "", "minimum", "");
375397
VALIDATE(s, "-9223372036854775807", true);
398+
VALIDATE(s, "-2147483648", true); // int min
399+
VALIDATE(s, "0", true);
400+
VALIDATE(s, "2147483647", true); // int max
401+
VALIDATE(s, "2147483648", true); // unsigned first
402+
VALIDATE(s, "4294967296", true); // unsigned max
403+
VALIDATE(s, "9223372036854775806", true);
404+
INVALIDATE(s, "9223372036854775807", "", "maximum", "");
405+
INVALIDATE(s, "18446744073709551615", "", "maximum", ""); // uint64_t max
406+
}
407+
408+
TEST(SchemaValidator, Integer_RangeU64Boundary) {
409+
Document sd;
410+
sd.Parse("{\"type\":\"integer\",\"minimum\":9223372036854775808,\"maximum\":18446744073709551614}");
411+
SchemaDocument s(sd);
412+
413+
INVALIDATE(s, "-9223372036854775808", "", "minimum", "");
414+
INVALIDATE(s, "9223372036854775807", "", "minimum", "");
415+
INVALIDATE(s, "-2147483648", "", "minimum", ""); // int min
416+
INVALIDATE(s, "0", "", "minimum", "");
417+
INVALIDATE(s, "2147483647", "", "minimum", ""); // int max
418+
INVALIDATE(s, "2147483648", "", "minimum", ""); // unsigned first
419+
INVALIDATE(s, "4294967296", "", "minimum", ""); // unsigned max
420+
VALIDATE(s, "9223372036854775808", true);
376421
VALIDATE(s, "18446744073709551614", true);
377422
INVALIDATE(s, "18446744073709551615", "", "maximum", "");
378423
}
@@ -418,10 +463,37 @@ TEST(SchemaValidator, Number_Range) {
418463

419464
INVALIDATE(s, "-1", "", "minimum", "");
420465
VALIDATE(s, "0", true);
466+
VALIDATE(s, "0.1", true);
421467
VALIDATE(s, "10", true);
422468
VALIDATE(s, "99", true);
469+
VALIDATE(s, "99.9", true);
423470
INVALIDATE(s, "100", "", "maximum", "");
471+
INVALIDATE(s, "100.0", "", "maximum", "");
472+
INVALIDATE(s, "101.5", "", "maximum", "");
473+
}
474+
475+
TEST(SchemaValidator, Number_RangeDouble) {
476+
Document sd;
477+
sd.Parse("{\"type\":\"number\",\"minimum\":0.1,\"maximum\":100.1,\"exclusiveMaximum\":true}");
478+
SchemaDocument s(sd);
479+
480+
INVALIDATE(s, "-9223372036854775808", "", "minimum", "");
481+
INVALIDATE(s, "-2147483648", "", "minimum", ""); // int min
482+
INVALIDATE(s, "-1", "", "minimum", "");
483+
VALIDATE(s, "0.1", true);
484+
VALIDATE(s, "10", true);
485+
VALIDATE(s, "99", true);
486+
VALIDATE(s, "100", true);
424487
INVALIDATE(s, "101", "", "maximum", "");
488+
INVALIDATE(s, "101.5", "", "maximum", "");
489+
INVALIDATE(s, "18446744073709551614", "", "maximum", "");
490+
INVALIDATE(s, "18446744073709551615", "", "maximum", "");
491+
INVALIDATE(s, "2147483647", "", "maximum", ""); // int max
492+
INVALIDATE(s, "2147483648", "", "maximum", ""); // unsigned first
493+
INVALIDATE(s, "4294967296", "", "maximum", ""); // unsigned max
494+
INVALIDATE(s, "9223372036854775808", "", "maximum", "");
495+
INVALIDATE(s, "18446744073709551614", "", "maximum", "");
496+
INVALIDATE(s, "18446744073709551615", "", "maximum", "");
425497
}
426498

427499
TEST(SchemaValidator, Number_MultipleOf) {

0 commit comments

Comments
 (0)