diff options
author | Nikita Lapkov <nikita.lapkov@mongodb.com> | 2021-09-09 11:43:16 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-09-09 15:31:02 +0000 |
commit | 6d2d8a296b9e1dcb14c0e794f6d3c7f492a883fe (patch) | |
tree | d966744298492e4451235480ee79a4f3345c7dfb /src/mongo/db/query/datetime | |
parent | 1181ad492b061a582c7873c8ee610b098c9076b8 (diff) | |
download | mongo-6d2d8a296b9e1dcb14c0e794f6d3c7f492a883fe.tar.gz |
Revert "SERVER-59765 Improved 'amount' parameter validation for $dateAdd/$dateSubtract"
This reverts commit ec56b7edb4ffdee862df4b18c11690151253dde3.
Diffstat (limited to 'src/mongo/db/query/datetime')
-rw-r--r-- | src/mongo/db/query/datetime/date_time_support.cpp | 50 | ||||
-rw-r--r-- | src/mongo/db/query/datetime/date_time_support_test.cpp | 94 |
2 files changed, 2 insertions, 142 deletions
diff --git a/src/mongo/db/query/datetime/date_time_support.cpp b/src/mongo/db/query/datetime/date_time_support.cpp index 358fd6150c6..fb38063b0af 100644 --- a/src/mongo/db/query/datetime/date_time_support.cpp +++ b/src/mongo/db/query/datetime/date_time_support.cpp @@ -635,8 +635,7 @@ inline long leapYearsSinceReferencePoint(long year) { /** * Sums the number of days in the Gregorian calendar in years: 'startYear', - * 'startYear'+1, .., 'endYear'-1. 'startYear' and 'endYear' are expected to be from the range - * (-1000'000'000; +1000'000'000). + * 'startYear'+1, .., 'endYear'-1. */ inline long long daysBetweenYears(long startYear, long endYear) { return leapYearsSinceReferencePoint(endYear - 1) - leapYearsSinceReferencePoint(startYear - 1) + @@ -1135,45 +1134,6 @@ std::pair<Date_t, Date> defaultReferencePointForDateTrunc(const TimeZone& timezo } return {Date_t::fromMillisSinceEpoch(referencePointMillis), referencePoint}; } - -/** - * Determines if function 'dateAdd()' parameter 'amount' and 'unit' values are valid - the - * amount roughly fits the range of Date_t type. - */ -bool isDateAddAmountValid(long long amount, TimeUnit unit) { - constexpr long long maxDays{ - std::numeric_limits<unsigned long long>::max() / kMillisecondsPerDay + 1}; - constexpr auto maxYears = maxDays / 365 /* minimum number of days per year*/ + 1; - constexpr auto maxQuarters = maxYears * kQuartersPerYear; - constexpr auto maxMonths = maxYears * kMonthsInOneYear; - constexpr auto maxWeeks = maxDays / kDaysPerWeek; - constexpr auto maxHours = maxDays * kHoursPerDay; - constexpr auto maxMinutes = maxHours * kMinutesPerHour; - constexpr auto maxSeconds = maxMinutes * kSecondsPerMinute; - const auto maxAbsoluteAmountValue = [](TimeUnit unit) { - switch (unit) { - case TimeUnit::year: - return maxYears; - case TimeUnit::quarter: - return maxQuarters; - case TimeUnit::month: - return maxMonths; - case TimeUnit::week: - return maxWeeks; - case TimeUnit::day: - return maxDays; - case TimeUnit::hour: - return maxHours; - case TimeUnit::minute: - return maxMinutes; - case TimeUnit::second: - return maxSeconds; - default: - MONGO_UNREACHABLE_TASSERT(5976501); - } - }(unit); - return -maxAbsoluteAmountValue < amount && amount < maxAbsoluteAmountValue; -} } // namespace Date_t dateAdd(Date_t date, TimeUnit unit, long long amount, const TimeZone& timezone) { @@ -1181,14 +1141,6 @@ Date_t dateAdd(Date_t date, TimeUnit unit, long long amount, const TimeZone& tim return date + Milliseconds(amount); } - // Check that 'amount' value is within an acceptable range. If the value is within acceptable - // range, then the addition algorithm is expected to not overflow. The final determination if - // the result can be represented as Date_t is done after the addition result is computed. - uassert(5976500, - str::stream() << "invalid dateAdd 'amount' parameter value: " << amount << " " - << serializeTimeUnit(unit), - isDateAddAmountValid(amount, unit)); - auto localTime = timezone.getTimelibTime(date); auto microSec = durationCount<Microseconds>(Milliseconds(date.toMillisSinceEpoch() % 1000)); localTime->us = microSec; diff --git a/src/mongo/db/query/datetime/date_time_support_test.cpp b/src/mongo/db/query/datetime/date_time_support_test.cpp index d2b2e3b2d44..049b7fee220 100644 --- a/src/mongo/db/query/datetime/date_time_support_test.cpp +++ b/src/mongo/db/query/datetime/date_time_support_test.cpp @@ -2174,7 +2174,7 @@ TEST(TruncateDate, ErrorHandling) { ASSERT_THROWS_CODE( truncateDate(dateBeforeReferencePoint, TimeUnit::year, 1'000'000'000ULL, *timezone), AssertionException, - 5976500); + 5166406); // Verify computation with large bin size when the result is in the long past succeeds. ASSERT_EQ(timezone->createFromDateParts(-200'000'000LL, 1, 1, 0, 0, 0, 0), @@ -2207,90 +2207,6 @@ TEST(DateAdd, DateAddYear) { kDefaultTimeZone.createFromDateParts(2012, 2, 29, 0, 0, 0, 0)); } -TEST(DateAdd, LargeAmountValues) { - const auto anyDate = kDefaultTimeZone.createFromDateParts(2016, 1, 1, 0, 0, 0, 0); - const auto smallDate = kDefaultTimeZone.createFromDateParts(-291'000'000, 3, 31, 0, 0, 0, 0); - struct TestCase { - TimeUnit unit; - long long invalidAmount; // Amount value rejected in initial validation. - long long overflowAmount; // Amount to add to date -200'000'000-2-29 00:00:00.000 so the - // result cannot be represented as Date_t. - long long largeAmount; // Large amount to add to 'smallDate' so the result is equal to - // 'largeAmountExpectedDate'. - Date_t largeAmountExpectedDate; - }; - const auto maxValidYearAmountPlus1{584'942'417LL + 1}; - const auto maxValidDayAmountPlus1{213'503'982'334LL + 1}; - const std::vector<TestCase> testCases{ - {TimeUnit::year, - maxValidYearAmountPlus1, // Invalid amount. - maxValidYearAmountPlus1 - 1, // Overflow amount. - 550'000'000LL, // Large amount. - kDefaultTimeZone.createFromDateParts(-291'000'000 + 550'000'000, 3, 31, 0, 0, 0, 0)}, - {TimeUnit::quarter, - maxValidYearAmountPlus1 * 4, // Invalid amount. - maxValidYearAmountPlus1 * 4 - 1, // Overflow amount. - 550'000'000LL * 4, // Large amount. - kDefaultTimeZone.createFromDateParts(-291'000'000 + 550'000'000, 3, 31, 0, 0, 0, 0)}, - {TimeUnit::month, - maxValidYearAmountPlus1 * 12, // Invalid amount. - maxValidYearAmountPlus1 * 12 - 1, // Overflow amount. - 550'000'000LL * 12, // Large amount. - kDefaultTimeZone.createFromDateParts(-291'000'000 + 550'000'000, 3, 31, 0, 0, 0, 0)}, - {TimeUnit::day, - maxValidDayAmountPlus1, // Invalid amount. - maxValidDayAmountPlus1 - 1, // Overflow amount. - 250'000'000LL * 365, // Large amount. - smallDate + Days(250'000'000LL * 365)}, - {TimeUnit::hour, - maxValidDayAmountPlus1 * 24, // Invalid amount. - maxValidDayAmountPlus1 * 24 - 1, // Overflow amount. - 250'000'000LL * 365 * 24, // Large amount. - smallDate + Days(250'000'000LL * 365)}, - {TimeUnit::minute, - maxValidDayAmountPlus1 * 24 * 60, // Invalid amount. - maxValidDayAmountPlus1 * 24 * 60 - 1, // Overflow amount. - 250'000'000LL * 365 * 24 * 60, // Large amount. - smallDate + Days(250'000'000LL * 365)}, - {TimeUnit::second, - maxValidDayAmountPlus1 * 24 * 60 * 60, // Invalid amount. - maxValidDayAmountPlus1 * 24 * 60 * 60 - 1, // Overflow amount. - 250'000'000LL * 365 * 24 * 60 * 60, // Large amount. - smallDate + Days(250'000'000LL * 365)}, - }; - int testCaseIdx{0}; - for (auto&& testCase : testCases) { - // Verify that out-of-range amount values are rejected. - ASSERT_THROWS_CODE( - dateAdd(anyDate, testCase.unit, testCase.invalidAmount, kDefaultTimeZone), - AssertionException, - 5976500) - << " test case# " << testCaseIdx; - ASSERT_THROWS_CODE( - dateAdd(anyDate, testCase.unit, -testCase.invalidAmount, kDefaultTimeZone), - AssertionException, - 5976500) - << " test case# " << testCaseIdx; - - // Verify that overflow is detected when the result cannot be represented as Date_t. - ASSERT_THROWS_CODE( - dateAdd(kDefaultTimeZone.createFromDateParts(-200'000'000, 2, 29, 0, 0, 0, 0), - testCase.unit, - testCase.overflowAmount, - kDefaultTimeZone), - AssertionException, - 5166406) - << " test case# " << testCaseIdx; - - // Verify that adding large values works correctly. - ASSERT_EQ(dateAdd(smallDate, testCase.unit, testCase.largeAmount, kDefaultTimeZone), - testCase.largeAmountExpectedDate) - << " test case# " << testCaseIdx; - - ++testCaseIdx; - } -} - TEST(DateAdd, DateAddQuarter) { auto startDate = kDefaultTimeZone.createFromDateParts(2020, 1, 1, 0, 0, 0, 3); ASSERT_EQ(dateAdd(startDate, TimeUnit::quarter, 1, kDefaultTimeZone), @@ -2934,14 +2850,6 @@ TEST(DateAdd, DateAddMillisecond) { ASSERT_EQ(dateAdd(startDate, TimeUnit::millisecond, -1501, kDefaultTimeZone), kDefaultTimeZone.createFromDateParts(2020, 12, 31, 23, 59, 13, 500)); - - // Verify that an overflow is detected. - ASSERT_THROWS_CODE(dateAdd(startDate, - TimeUnit::millisecond, - std::numeric_limits<long long>::max(), - kDefaultTimeZone), - AssertionException, - ErrorCodes::Error::DurationOverflow); } TEST(IsValidDayOfWeek, Basic) { |