Skip to content

Commit

Permalink
validate year
Browse files Browse the repository at this point in the history
  • Loading branch information
caton-hpg committed Aug 25, 2022
1 parent 50c0c0a commit 706b471
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 19 deletions.
9 changes: 5 additions & 4 deletions src/common/function/test/FunctionManagerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,9 @@ TEST_F(FunctionManagerTest, time) {
{ TEST_FUNCTION(date, {Map({{"year", 2021}, {"month", 4}, {"day", 31}})}, Value::kNullBadData); }
// range [(−32,768, 1, 1), (32,767, 12, 31)]
{
TEST_FUNCTION(
date, {Map({{"year", -32767}, {"month", 1}, {"day", 1}})}, Value(Date(-32767, 1, 1)));
TEST_FUNCTION(date,
{Map({{"year", std::numeric_limits<int16_t>::min()}, {"month", 1}, {"day", 1}})},
Value(Date(std::numeric_limits<int16_t>::min(), 1, 1)));
}
{
TEST_FUNCTION(
Expand Down Expand Up @@ -686,13 +687,13 @@ TEST_F(FunctionManagerTest, time) {
// range [(−32,768, 1, 1, 0, 0, 0, 0), (32,767, 12, 31, 23, 59, 59, 999999)]
{
TEST_FUNCTION(datetime,
{Map({{"year", -32767},
{Map({{"year", -32768},
{"month", 1},
{"day", 1},
{"hour", 0},
{"minute", 0},
{"second", 0}})},
Value(time::TimeUtils::dateTimeToUTC(DateTime(-32767, 1, 1, 0, 0, 0, 0))));
Value(time::TimeUtils::dateTimeToUTC(DateTime(-32768, 1, 1, 0, 0, 0, 0))));
}
{
TEST_FUNCTION(datetime,
Expand Down
15 changes: 7 additions & 8 deletions src/common/time/TimeUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ constexpr int64_t kMaxTimestamp = std::numeric_limits<int64_t>::max() / 10000000
return Status::Error("Invalid value type.");
}
if (kv.first == "year") {
// year should be in [-32767, 32767] and same as parser
if (kv.second.getInt() <= std::numeric_limits<int16_t>::min() ||
kv.second.getInt() > std::numeric_limits<int16_t>::max()) {
return Status::Error("Out of range year `%ld'.", kv.second.getInt());
auto result = validateYear(kv.second.getInt());
if (!result.ok()) {
return result;
}

dt.year = kv.second.getInt();
} else if (kv.first == "month") {
if (kv.second.getInt() <= 0 || kv.second.getInt() > 12) {
Expand Down Expand Up @@ -84,10 +84,9 @@ constexpr int64_t kMaxTimestamp = std::numeric_limits<int64_t>::max() / 10000000
return Status::Error("Invalid value type.");
}
if (kv.first == "year") {
// year should be in [-32767, 32767] and same as parser
if (kv.second.getInt() <= std::numeric_limits<int16_t>::min() ||
kv.second.getInt() > std::numeric_limits<int16_t>::max()) {
return Status::Error("Out of range year `%ld'.", kv.second.getInt());
auto result = validateYear(kv.second.getInt());
if (!result.ok()) {
return result;
}
d.year = kv.second.getInt();
} else if (kv.first == "month") {
Expand Down
7 changes: 7 additions & 0 deletions src/common/time/TimeUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ class TimeUtils {
return Status::OK();
}

static Status validateYear(int64_t year) {
if (year < std::numeric_limits<int16_t>::min() || year > std::numeric_limits<int16_t>::max()) {
return Status::Error("Out of range year `%ld'.", year);
}
return Status::OK();
}

template <
typename D,
typename = std::enable_if_t<std::is_same<D, Time>::value || std::is_same<D, DateTime>::value>>
Expand Down
36 changes: 30 additions & 6 deletions src/common/time/parser/datetime_parser.yy
Original file line number Diff line number Diff line change
Expand Up @@ -114,48 +114,72 @@ date_time_delimiter

date
: INTEGER NEGATIVE INTEGER NEGATIVE INTEGER {
auto result = nebula::time::TimeUtils::validateYear($1);
if (!result.ok()) {
throw DatetimeParser::syntax_error(@1, result.toString());
}
$$ = new nebula::Date($1, $3, $5);
auto result = nebula::time::TimeUtils::validateDate(*$$);
result = nebula::time::TimeUtils::validateDate(*$$);
if (!result.ok()) {
delete $$;
throw DatetimeParser::syntax_error(@1, result.toString());
}
}
| NEGATIVE INTEGER NEGATIVE INTEGER NEGATIVE INTEGER {
auto result = nebula::time::TimeUtils::validateYear(0-$2);
if (!result.ok()) {
throw DatetimeParser::syntax_error(@1, result.toString());
}
$$ = new nebula::Date(0-$2, $4, $6);
auto result = nebula::time::TimeUtils::validateDate(*$$);
result = nebula::time::TimeUtils::validateDate(*$$);
if (!result.ok()) {
delete $$;
throw DatetimeParser::syntax_error(@1, result.toString());
}
}
| INTEGER NEGATIVE INTEGER {
auto result = nebula::time::TimeUtils::validateYear($1);
if (!result.ok()) {
throw DatetimeParser::syntax_error(@1, result.toString());
}
$$ = new nebula::Date($1, $3, 1);
auto result = nebula::time::TimeUtils::validateDate(*$$);
result = nebula::time::TimeUtils::validateDate(*$$);
if (!result.ok()) {
delete $$;
throw DatetimeParser::syntax_error(@1, result.toString());
}
}
| NEGATIVE INTEGER NEGATIVE INTEGER {
auto result = nebula::time::TimeUtils::validateYear(0-$2);
if (!result.ok()) {
throw DatetimeParser::syntax_error(@1, result.toString());
}
$$ = new nebula::Date(0-$2, $4, 1);
auto result = nebula::time::TimeUtils::validateDate(*$$);
result = nebula::time::TimeUtils::validateDate(*$$);
if (!result.ok()) {
delete $$;
throw DatetimeParser::syntax_error(@1, result.toString());
}
}
| INTEGER {
auto result = nebula::time::TimeUtils::validateYear($1);
if (!result.ok()) {
throw DatetimeParser::syntax_error(@1, result.toString());
}
$$ = new nebula::Date($1, 1, 1);
auto result = nebula::time::TimeUtils::validateDate(*$$);
result = nebula::time::TimeUtils::validateDate(*$$);
if (!result.ok()) {
delete $$;
throw DatetimeParser::syntax_error(@1, result.toString());
}
}
| NEGATIVE INTEGER {
auto result = nebula::time::TimeUtils::validateYear(0-$2);
if (!result.ok()) {
throw DatetimeParser::syntax_error(@1, result.toString());
}
$$ = new nebula::Date(0-$2, 1, 1);
auto result = nebula::time::TimeUtils::validateDate(*$$);
result = nebula::time::TimeUtils::validateDate(*$$);
if (!result.ok()) {
delete $$;
throw DatetimeParser::syntax_error(@1, result.toString());
Expand Down
2 changes: 1 addition & 1 deletion src/common/time/parser/datetime_scanner.lex
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ R_BRACKET "]"
{DEC}+ {
try {
folly::StringPiece text(yytext, yyleng);
int16_t val = folly::to<int16_t>(text);
int64_t val = folly::to<int64_t>(text);
yylval->intVal = val;
} catch (...) {
throw DatetimeParser::syntax_error(*yylloc, "Invalid integer:");
Expand Down

0 comments on commit 706b471

Please sign in to comment.