summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/datetime
diff options
context:
space:
mode:
authorNikita Lapkov <nikita.lapkov@mongodb.com>2021-09-09 11:43:16 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-09-09 15:31:02 +0000
commit6d2d8a296b9e1dcb14c0e794f6d3c7f492a883fe (patch)
treed966744298492e4451235480ee79a4f3345c7dfb /src/mongo/db/query/datetime
parent1181ad492b061a582c7873c8ee610b098c9076b8 (diff)
downloadmongo-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.cpp50
-rw-r--r--src/mongo/db/query/datetime/date_time_support_test.cpp94
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) {