Skip to content

Commit

Permalink
Fix mktime/timegm for time_t > MAX_INT32
Browse files Browse the repository at this point in the history
Fixes: #19694
  • Loading branch information
sbc100 committed Jun 23, 2023
1 parent 98e3466 commit 6cee85e
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 18 deletions.
4 changes: 2 additions & 2 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ mergeInto(LibraryManager.library, {
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'date.getMonth()', 'i32') }}};
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_year, 'date.getYear()', 'i32') }}};
return (date.getTime() / 1000)|0;
return {{{ makeReturn64('date.getTime() / 1000') }}};
},
_gmtime_js__deps: ['$readI53FromI64'].concat(i53ConversionDeps),
Expand Down Expand Up @@ -510,7 +510,7 @@ mergeInto(LibraryManager.library, {
var yday = ((date.getTime() - start) / (1000 * 60 * 60 * 24))|0;
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}};
return (date.getTime() / 1000)|0;
return {{{ makeReturn64('date.getTime() / 1000') }}};
},
_localtime_js__deps: ['$readI53FromI64', '$ydayFromDate'].concat(i53ConversionDeps),
Expand Down
4 changes: 2 additions & 2 deletions src/library_sigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,12 @@ sigs = {
_emval_typeof__sig: 'pp',
_gmtime_js__sig: 'vjp',
_localtime_js__sig: 'vjp',
_mktime_js__sig: 'ip',
_mktime_js__sig: 'jp',
_mmap_js__sig: 'ipiiijpp',
_msync_js__sig: 'ippiiij',
_munmap_js__sig: 'ippiiij',
_setitimer_js__sig: 'iid',
_timegm_js__sig: 'ip',
_timegm_js__sig: 'jp',
_tzset_js__sig: 'vppp',
_wasmfs_copy_preloaded_file_data__sig: 'vip',
_wasmfs_create_fetch_backend_js__sig: 'vp',
Expand Down
2 changes: 1 addition & 1 deletion src/modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ global.LibraryManager = {

// Core system libraries (always linked against)
let libraries = [
'library_int53.js',
'library.js',
'library_sigs.js',
'library_int53.js',
'library_ccall.js',
'library_addfunction.js',
'library_formatString.js',
Expand Down
8 changes: 2 additions & 6 deletions system/lib/libc/emscripten_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,8 @@ void emscripten_memset_big(void* ptr, char value, size_t n);

void emscripten_notify_memory_growth(size_t memory_index);

// Declare these functions `int` rather than time_t to avoid int64 at the wasm
// boundary (avoids 64-bit complexity at the boundary when WASM_BIGINT is
// missing).
// TODO(sbc): Covert back to `time_t` before 2038 ...
int _timegm_js(struct tm* tm);
int _mktime_js(struct tm* tm);
time_t _timegm_js(struct tm* tm);
time_t _mktime_js(struct tm* tm);
void _localtime_js(time_t t, struct tm* __restrict__ tm);
void _gmtime_js(time_t t, struct tm* __restrict__ tm);

Expand Down
14 changes: 7 additions & 7 deletions test/core/test_time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
#include <assert.h>
#include <math.h>

void
check_gmtime_localtime(time_t time)
void check_gmtime_localtime(time_t time)
{
char gmbuf[32], locbuf[32];
const char fmt[] = "%Y-%m-%d %H:%M:%S";
Expand Down Expand Up @@ -46,7 +45,7 @@ int main() {
tzset();
printf("tzname[0] set: %d\n", strlen(tzname[0]) >= 3);
printf("tzname[1] set: %d\n", strlen(tzname[1]) >= 3);

// Verify gmtime() creates correct struct.
tm_ptr = gmtime(&xmas2002);
printf("sec: %d\n", tm_ptr->tm_sec);
Expand All @@ -60,7 +59,7 @@ int main() {
printf("dst: %d\n", tm_ptr->tm_isdst);
printf("off: %ld\n", (long)tm_ptr->tm_gmtoff);
printf("zone: %s\n", tm_ptr->tm_zone);

// Verify timegm() reverses gmtime; run through an entire year in half hours.
int timegmOk = 1;
for (int i = 0; i < 2*24*266; ++i) {
Expand All @@ -75,14 +74,14 @@ int main() {
timegmOk = 0;
}
printf("timegm <-> gmtime: %d\n", timegmOk);

// Verify gmtime_r() doesn't clobber static data.
time_t t1 = 0;
struct tm tm1;
gmtime_r(&t1, &tm1);
printf("old year still: %d\n", tm_ptr->tm_year);
printf("new year: %d\n", tm1.tm_year);

// Verify localtime() picks up timezone data.
struct tm tm_winter, tm_summer;
if (localtime_r(&xmas2002, &tm_winter) != &tm_winter) printf("localtime_r failed\n");
Expand Down Expand Up @@ -152,7 +151,7 @@ int main() {
tm2.tm_hour != tm_local.tm_hour || tm2.tm_mday != tm_local.tm_mday ||
tm2.tm_mon != tm_local.tm_mon || tm2.tm_year != tm_local.tm_year ||
tm2.tm_wday != tm_local.tm_wday || tm2.tm_yday != tm_local.tm_yday);

printf("mktime parameter is equivalent to localtime return: %d\n", mktimeOk);

// Verify that mktime is able to guess what the dst is. It might get it wrong
Expand Down Expand Up @@ -249,6 +248,7 @@ int main() {
check_gmtime_localtime(-2147483649);
check_gmtime_localtime(253402300799); // end of year 9999
check_gmtime_localtime(-62135596800); // beginning of year 1
check_gmtime_localtime(0x83d4d9a5); // some time in 2040 (time_t > MAX_INT32)

// check that localtime sets tm_yday correctly whenever the day rolls over (issue #17635)
// prior to being fixed, tm_yday did not increment correctly at epoch time 1049061599 (2003-03-31 00:00:00) in CET time
Expand Down
1 change: 1 addition & 0 deletions test/core/test_time.out
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,5 @@ time: -2147483648, gmtime: 1901-12-13 20:45:52
time: -2147483649, gmtime: 1901-12-13 20:45:51
time: 253402300799, gmtime: 9999-12-31 23:59:59
time: -62135596800, gmtime: 1-01-01 00:00:00
time: 2211764645, gmtime: 2040-02-02 03:04:05
success

0 comments on commit 6cee85e

Please sign in to comment.