diff options
author | Derick Rethans <github@derickrethans.nl> | 2017-06-30 15:31:20 +0200 |
---|---|---|
committer | Derick Rethans <github@derickrethans.nl> | 2017-06-30 17:38:20 +0200 |
commit | fbcf295fff8fe1723120345126be90a49d7b6d14 (patch) | |
tree | f8df12f08748caeb8093b646e7607700ce13d281 /src/mongo/db | |
parent | 9fb03a72fb42fa8c2880369889efbf46b85a9f08 (diff) | |
download | mongo-fbcf295fff8fe1723120345126be90a49d7b6d14.tar.gz |
SERVER-28613: Fixed memory leak while fetching a timelib_time.
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/query/datetime/date_time_support.cpp | 29 | ||||
-rw-r--r-- | src/mongo/db/query/datetime/date_time_support.h | 9 |
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 |