diff options
author | Timothy Flynn <trflynn89@pm.me> | 2022-08-01 14:59:17 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-08-02 21:10:44 +0100 |
commit | e683ca00ccc17816b7af1b5311baf406552c6331 (patch) | |
tree | 13027ad2949d3ff86b64aeea143f3b5a2e1bb473 /Userland/Libraries/LibC/time.cpp | |
parent | 91e3a2aaca740e70279508d17f5f12805ca78bc7 (diff) | |
download | serenity-e683ca00ccc17816b7af1b5311baf406552c6331.zip |
LibC: Split time_t range validation to separate helper function
Right now, the tm_to_time helper invokes time_to_tm to validate the
time_t it creates. Soon, both tm_to_time and time_to_tm will perform
some TZDB lookups to handle DST. This isn't a huge cost, but let's
avoid the double lookup here.
Diffstat (limited to 'Userland/Libraries/LibC/time.cpp')
-rw-r--r-- | Userland/Libraries/LibC/time.cpp | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/Userland/Libraries/LibC/time.cpp b/Userland/Libraries/LibC/time.cpp index f43b8ad32f..c1df69c6a5 100644 --- a/Userland/Libraries/LibC/time.cpp +++ b/Userland/Libraries/LibC/time.cpp @@ -102,13 +102,19 @@ char* ctime_r(time_t const* t, char* buf) static int const __seconds_per_day = 60 * 60 * 24; -static struct tm* time_to_tm(struct tm* tm, time_t t) +static bool is_valid_time(time_t timestamp) { // Note: these correspond to the number of seconds from epoch to the dates "Jan 1 00:00:00 -2147483648" and "Dec 31 23:59:59 2147483647", // respectively, which are the smallest and biggest representable dates without overflowing tm->tm_year, if it is an int. constexpr time_t smallest_possible_time = -67768040609740800; constexpr time_t biggest_possible_time = 67768036191676799; - if (t < smallest_possible_time || t > biggest_possible_time) { + + return (timestamp >= smallest_possible_time) && (timestamp <= biggest_possible_time); +} + +static struct tm* time_to_tm(struct tm* tm, time_t t) +{ + if (!is_valid_time(t)) { errno = EOVERFLOW; return nullptr; } @@ -162,8 +168,12 @@ static time_t tm_to_time(struct tm* tm, long timezone_adjust_seconds) tm->tm_yday = day_of_year(1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday); time_t days_since_epoch = years_to_days_since_epoch(1900 + tm->tm_year) + tm->tm_yday; auto timestamp = ((days_since_epoch * 24 + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec + timezone_adjust_seconds; - if (!time_to_tm(tm, timestamp)) + + if (!is_valid_time(timestamp)) { + errno = EOVERFLOW; return -1; + } + return timestamp; } |