Skip to content

Commit

Permalink
Fix a bug in schema minimum/maximum keywords for 64-bit integer
Browse files Browse the repository at this point in the history
  • Loading branch information
miloyip committed Apr 16, 2016
1 parent ecd8fa3 commit 26e69ff
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
9 changes: 9 additions & 0 deletions include/rapidjson/schema.h
Expand Up @@ -1108,6 +1108,9 @@ class Schema {
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<double>(i)))
return false;
}
Expand All @@ -1117,6 +1120,8 @@ class Schema {
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<double>(i)))
return false;
}
Expand All @@ -1142,6 +1147,8 @@ class Schema {
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<double>(i)))
return false;
}
Expand All @@ -1151,6 +1158,8 @@ class Schema {
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<double>(i)))
return false;
}
Expand Down
74 changes: 73 additions & 1 deletion test/unittest/schematest.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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", "");
}
Expand All @@ -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", "");
}
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 26e69ff

Please sign in to comment.