summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/datetime
diff options
context:
space:
mode:
authorDerick Rethans <github@derickrethans.nl>2017-06-30 15:31:20 +0200
committerDerick Rethans <github@derickrethans.nl>2017-06-30 17:38:20 +0200
commitfbcf295fff8fe1723120345126be90a49d7b6d14 (patch)
treef8df12f08748caeb8093b646e7607700ce13d281 /src/mongo/db/query/datetime
parent9fb03a72fb42fa8c2880369889efbf46b85a9f08 (diff)
downloadmongo-fbcf295fff8fe1723120345126be90a49d7b6d14.tar.gz
SERVER-28613: Fixed memory leak while fetching a timelib_time.
Diffstat (limited to 'src/mongo/db/query/datetime')
-rw-r--r--src/mongo/db/query/datetime/date_time_support.cpp29
-rw-r--r--src/mongo/db/query/datetime/date_time_support.h9
2 files changed, 25 insertions, 13 deletions
diff --git a/src/mongo/db/query/datetime/date_time_support.cpp b/src/mongo/db/query/datetime/date_time_support.cpp
index 6cf60889c85..1356356665d 100644
--- a/src/mongo/db/query/datetime/date_time_support.cpp
+++ b/src/mongo/db/query/datetime/date_time_support.cpp
@@ -231,31 +231,36 @@ void TimeZone::TimelibTZInfoDeleter::operator()(timelib_tzinfo* tzInfo) {
TimeZone::TimeZone(timelib_tzinfo* tzInfo) : _tzInfo(tzInfo, TimelibTZInfoDeleter()) {}
-timelib_time TimeZone::getTimelibTime(Date_t date) const {
- timelib_time time{};
+void TimeZone::TimelibTimeDeleter::operator()(timelib_time* time) {
+ timelib_time_dtor(time);
+}
+
+std::unique_ptr<timelib_time, TimeZone::TimelibTimeDeleter> TimeZone::getTimelibTime(
+ Date_t date) const {
+ std::unique_ptr<timelib_time, TimeZone::TimelibTimeDeleter> time(timelib_time_ctor());
if (_tzInfo) {
- timelib_set_timezone(&time, _tzInfo.get());
- timelib_unixtime2local(&time, seconds(date));
+ timelib_set_timezone(time.get(), _tzInfo.get());
+ timelib_unixtime2local(time.get(), seconds(date));
} else {
- timelib_unixtime2gmt(&time, seconds(date));
+ timelib_unixtime2gmt(time.get(), seconds(date));
}
return time;
}
TimeZone::Iso8601DateParts TimeZone::dateIso8601Parts(Date_t date) const {
auto time = getTimelibTime(date);
- return Iso8601DateParts(time, date);
+ return Iso8601DateParts(*time, date);
}
TimeZone::DateParts TimeZone::dateParts(Date_t date) const {
auto time = getTimelibTime(date);
- return DateParts(time, date);
+ return DateParts(*time, date);
}
int TimeZone::dayOfWeek(Date_t date) const {
auto time = getTimelibTime(date);
// timelib_day_of_week() returns a number in the range [0,6], we want [1,7], so add one.
- return timelib_day_of_week(time.y, time.m, time.d) + 1;
+ return timelib_day_of_week(time->y, time->m, time->d) + 1;
}
int TimeZone::week(Date_t date) const {
@@ -274,19 +279,19 @@ int TimeZone::week(Date_t date) const {
int TimeZone::dayOfYear(Date_t date) const {
auto time = getTimelibTime(date);
// timelib_day_of_year() returns a number in the range [0,365], we want [1,366], so add one.
- return timelib_day_of_year(time.y, time.m, time.d) + 1;
+ return timelib_day_of_year(time->y, time->m, time->d) + 1;
}
int TimeZone::isoDayOfWeek(Date_t date) const {
auto time = getTimelibTime(date);
- return timelib_iso_day_of_week(time.y, time.m, time.d);
+ return timelib_iso_day_of_week(time->y, time->m, time->d);
}
int TimeZone::isoWeek(Date_t date) const {
auto time = getTimelibTime(date);
long long isoWeek;
long long isoYear;
- timelib_isoweek_from_date(time.y, time.m, time.d, &isoWeek, &isoYear);
+ timelib_isoweek_from_date(time->y, time->m, time->d, &isoWeek, &isoYear);
return isoWeek;
}
@@ -294,7 +299,7 @@ long long TimeZone::isoYear(Date_t date) const {
auto time = getTimelibTime(date);
long long isoWeek;
long long isoYear;
- timelib_isoweek_from_date(time.y, time.m, time.d, &isoWeek, &isoYear);
+ timelib_isoweek_from_date(time->y, time->m, time->d, &isoWeek, &isoYear);
return isoYear;
}
diff --git a/src/mongo/db/query/datetime/date_time_support.h b/src/mongo/db/query/datetime/date_time_support.h
index 1108db1e022..6f1e43aafad 100644
--- a/src/mongo/db/query/datetime/date_time_support.h
+++ b/src/mongo/db/query/datetime/date_time_support.h
@@ -79,6 +79,13 @@ public:
int millisecond;
};
+ /**
+ * A custom-deleter which destructs a timelib_time* when it goes out of scope.
+ */
+ struct TimelibTimeDeleter {
+ TimelibTimeDeleter() = default;
+ void operator()(timelib_time* time);
+ };
explicit TimeZone(timelib_tzinfo* tzInfo);
TimeZone() = default;
@@ -230,7 +237,7 @@ public:
static void validateFormat(StringData format);
private:
- timelib_time getTimelibTime(Date_t) const;
+ std::unique_ptr<timelib_time, TimelibTimeDeleter> getTimelibTime(Date_t) const;
/**
* Only works with 1 <= spaces <= 4 and 0 <= number <= 9999. If spaces is less than the digit