From 26e69ffde95ba4773ab06db6457b78f308716f4b Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Sun, 17 Apr 2016 00:48:02 +0800 Subject: [PATCH] Fix a bug in schema minimum/maximum keywords for 64-bit integer --- include/rapidjson/schema.h | 9 +++++ test/unittest/schematest.cpp | 74 +++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/include/rapidjson/schema.h b/include/rapidjson/schema.h index e12e7d2d..5efbf245 100644 --- a/include/rapidjson/schema.h +++ b/include/rapidjson/schema.h @@ -1108,6 +1108,9 @@ private: if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); } + else if (minimum_.IsUint64()) { + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64() + } else if (!CheckDoubleMinimum(context, static_cast(i))) return false; } @@ -1117,6 +1120,8 @@ private: if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); } + else if (maximum_.IsUint64()) + /* do nothing */; // i <= max(int64_t) < maximum_.GetUint64() else if (!CheckDoubleMaximum(context, static_cast(i))) return false; } @@ -1142,6 +1147,8 @@ private: if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); } + else if (minimum_.IsInt64()) + /* do nothing */; // i >= 0 > minimum.Getint64() else if (!CheckDoubleMinimum(context, static_cast(i))) return false; } @@ -1151,6 +1158,8 @@ private: if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); } + else if (maximum_.IsInt64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_ else if (!CheckDoubleMaximum(context, static_cast(i))) return false; } diff --git a/test/unittest/schematest.cpp b/test/unittest/schematest.cpp index 7182ad29..23aac0ee 100644 --- a/test/unittest/schematest.cpp +++ b/test/unittest/schematest.cpp @@ -51,6 +51,10 @@ TEST(SchemaValidator, Hasher) { TEST_HASHER("false", "null", false); TEST_HASHER("1", "1", true); + TEST_HASHER("2147483648", "2147483648", true); // 2^31 can only be fit in unsigned + TEST_HASHER("-2147483649", "-2147483649", true); // -2^31 - 1 can only be fit in int64_t + TEST_HASHER("2147483648", "2147483648", true); // 2^31 can only be fit in unsigned + TEST_HASHER("4294967296", "4294967296", true); // 2^32 can only be fit in int64_t TEST_HASHER("1.5", "1.5", true); TEST_HASHER("1", "1.0", true); TEST_HASHER("1", "-1", false); @@ -316,6 +320,10 @@ TEST(SchemaValidator, String) { VALIDATE(s, "\"I'm a string\"", true); INVALIDATE(s, "42", "", "type", ""); + INVALIDATE(s, "2147483648", "", "type", ""); // 2^31 can only be fit in unsigned + INVALIDATE(s, "-2147483649", "", "type", ""); // -2^31 - 1 can only be fit in int64_t + INVALIDATE(s, "4294967296", "", "type", ""); // 2^32 can only be fit in int64_t + INVALIDATE(s, "3.1415926", "", "type", ""); } TEST(SchemaValidator, String_LengthRange) { @@ -340,6 +348,16 @@ TEST(SchemaValidator, String_Pattern) { INVALIDATE(s, "\"(888)555-1212 ext. 532\"", "", "pattern", ""); INVALIDATE(s, "\"(800)FLOWERS\"", "", "pattern", ""); } + +TEST(SchemaValidator, String_Pattern_Invalid) { + Document sd; + sd.Parse("{\"type\":\"string\",\"pattern\":\"a{0}\"}"); // TODO: report regex is invalid somehow + SchemaDocument s(sd); + + VALIDATE(s, "\"\"", true); + VALIDATE(s, "\"a\"", true); + VALIDATE(s, "\"aa\"", true); +} #endif TEST(SchemaValidator, Integer) { @@ -349,6 +367,10 @@ TEST(SchemaValidator, Integer) { VALIDATE(s, "42", true); VALIDATE(s, "-1", true); + VALIDATE(s, "2147483648", true); // 2^31 can only be fit in unsigned + VALIDATE(s, "-2147483649", true); // -2^31 - 1 can only be fit in int64_t + VALIDATE(s, "2147483648", true); // 2^31 can only be fit in unsigned + VALIDATE(s, "4294967296", true); // 2^32 can only be fit in int64_t INVALIDATE(s, "3.1415926", "", "type", ""); INVALIDATE(s, "\"42\"", "", "type", ""); } @@ -368,11 +390,34 @@ TEST(SchemaValidator, Integer_Range) { TEST(SchemaValidator, Integer_Range64Boundary) { Document sd; - sd.Parse("{\"type\":\"integer\",\"minimum\":-9223372036854775807,\"maximum\":18446744073709551614}"); + sd.Parse("{\"type\":\"integer\",\"minimum\":-9223372036854775807,\"maximum\":9223372036854775806}"); SchemaDocument s(sd); INVALIDATE(s, "-9223372036854775808", "", "minimum", ""); VALIDATE(s, "-9223372036854775807", true); + VALIDATE(s, "-2147483648", true); // int min + VALIDATE(s, "0", true); + VALIDATE(s, "2147483647", true); // int max + VALIDATE(s, "2147483648", true); // unsigned first + VALIDATE(s, "4294967296", true); // unsigned max + VALIDATE(s, "9223372036854775806", true); + INVALIDATE(s, "9223372036854775807", "", "maximum", ""); + INVALIDATE(s, "18446744073709551615", "", "maximum", ""); // uint64_t max +} + +TEST(SchemaValidator, Integer_RangeU64Boundary) { + Document sd; + sd.Parse("{\"type\":\"integer\",\"minimum\":9223372036854775808,\"maximum\":18446744073709551614}"); + SchemaDocument s(sd); + + INVALIDATE(s, "-9223372036854775808", "", "minimum", ""); + INVALIDATE(s, "9223372036854775807", "", "minimum", ""); + INVALIDATE(s, "-2147483648", "", "minimum", ""); // int min + INVALIDATE(s, "0", "", "minimum", ""); + INVALIDATE(s, "2147483647", "", "minimum", ""); // int max + INVALIDATE(s, "2147483648", "", "minimum", ""); // unsigned first + INVALIDATE(s, "4294967296", "", "minimum", ""); // unsigned max + VALIDATE(s, "9223372036854775808", true); VALIDATE(s, "18446744073709551614", true); INVALIDATE(s, "18446744073709551615", "", "maximum", ""); } @@ -418,10 +463,37 @@ TEST(SchemaValidator, Number_Range) { INVALIDATE(s, "-1", "", "minimum", ""); VALIDATE(s, "0", true); + VALIDATE(s, "0.1", true); VALIDATE(s, "10", true); VALIDATE(s, "99", true); + VALIDATE(s, "99.9", true); INVALIDATE(s, "100", "", "maximum", ""); + INVALIDATE(s, "100.0", "", "maximum", ""); + INVALIDATE(s, "101.5", "", "maximum", ""); +} + +TEST(SchemaValidator, Number_RangeDouble) { + Document sd; + sd.Parse("{\"type\":\"number\",\"minimum\":0.1,\"maximum\":100.1,\"exclusiveMaximum\":true}"); + SchemaDocument s(sd); + + INVALIDATE(s, "-9223372036854775808", "", "minimum", ""); + INVALIDATE(s, "-2147483648", "", "minimum", ""); // int min + INVALIDATE(s, "-1", "", "minimum", ""); + VALIDATE(s, "0.1", true); + VALIDATE(s, "10", true); + VALIDATE(s, "99", true); + VALIDATE(s, "100", true); INVALIDATE(s, "101", "", "maximum", ""); + INVALIDATE(s, "101.5", "", "maximum", ""); + INVALIDATE(s, "18446744073709551614", "", "maximum", ""); + INVALIDATE(s, "18446744073709551615", "", "maximum", ""); + INVALIDATE(s, "2147483647", "", "maximum", ""); // int max + INVALIDATE(s, "2147483648", "", "maximum", ""); // unsigned first + INVALIDATE(s, "4294967296", "", "maximum", ""); // unsigned max + INVALIDATE(s, "9223372036854775808", "", "maximum", ""); + INVALIDATE(s, "18446744073709551614", "", "maximum", ""); + INVALIDATE(s, "18446744073709551615", "", "maximum", ""); } TEST(SchemaValidator, Number_MultipleOf) {