Skip to content

Commit 722a1b7

Browse files
authored
Fix for mktime + ASSERTIONS=2 (#26716)
There were two issues with the existing code: 1. Values were being written even when the Data was invalid. 2. In ASSERTIONS=2 these invalid values were causing assertions. Fixes: #26704
1 parent 347da58 commit 722a1b7

4 files changed

Lines changed: 32 additions & 14 deletions

File tree

src/lib/libtime.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ addToLibrary({
1717
{{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_min, 'i32') }}},
1818
{{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'i32') }}},
1919
0);
20+
if (isNaN(date.getTime())) {
21+
return -1;
22+
}
2023

2124
// There's an ambiguous hour when the time goes back; the tm_isdst field is
2225
// used to disambiguate it. Date() basically guesses, so we fix it up if it
@@ -48,12 +51,8 @@ addToLibrary({
4851
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'date.getMonth()', 'i32') }}};
4952
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_year, 'date.getYear()', 'i32') }}};
5053

51-
var timeMs = date.getTime();
52-
if (isNaN(timeMs)) {
53-
return -1;
54-
}
55-
// Return time in microseconds
56-
return timeMs / 1000;
54+
// Return time in seconds
55+
return date.getTime() / 1000;
5756
},
5857

5958
_gmtime_js__i53abi: true,

test/codesize/test_codesize_hello_dylink_all.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"a.out.js": 244278,
2+
"a.out.js": 244303,
33
"a.out.nodebug.wasm": 577664,
4-
"total": 821942,
4+
"total": 821967,
55
"sent": [
66
"IMG_Init",
77
"IMG_Load",

test/other/test_time.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <errno.h>
77
#include <stdio.h>
88
#include <stdlib.h>
9+
#include <stdint.h>
910
#include <time.h>
1011
#include <string.h>
1112
#include <assert.h>
@@ -27,7 +28,7 @@ void check_gmtime_localtime(time_t time) {
2728
assert(loc);
2829
assert(strftime(locbuf, sizeof(locbuf) - 1, fmt, loc) > 0);
2930

30-
printf("time: %lld, gmtime: %s\n", time, gmbuf);
31+
printf("time: %jd, gmtime: %s\n", (intmax_t)time, gmbuf);
3132

3233
// gmtime and localtime should be equal when timezone is UTC
3334
assert(timezone != 0 || strcmp(gmbuf, locbuf) == 0);
@@ -218,12 +219,28 @@ void test_yday() {
218219
}
219220

220221
void test_year_overflow() {
221-
// Verify that timestamps outside of the range supported by date.getNow()
222-
// cause failure with EOVERFLOW.
222+
// Verify that timestamps outside of the range supported JavaScript Date
223+
// object with result in a graceful failure with EOVERFLOW.
223224
struct tm tm_big = {0};
224-
tm_big.tm_year = 292278994;
225+
// The range of is approximately 273,790 years from the epoc in either
226+
// direction.
227+
tm_big.tm_year = 300000;
228+
struct tm tm_big_copy = tm_big;
229+
errno = 0;
225230
time_t tbig = mktime(&tm_big);
226-
assert((tbig == -1 && errno == EOVERFLOW) || tbig == 9223431975273600);
231+
#if defined(__EMSCRIPTEN__) && !defined(STANDALONE)
232+
assert(tbig == -1);
233+
assert(errno == EOVERFLOW);
234+
// When mktime fails with EOVERFLOW it should not touch the bits of
235+
// its argument.
236+
assert(memcmp(&tm_big, &tm_big_copy, sizeof(tm_big)) == 0);
237+
#else
238+
// Outside of emscripten, or in standalone mode mktime can support larger
239+
// values like this. According to the C standard, the range of tm_year (and
240+
// time_t) is implementation-defined
241+
assert(errno == 0);
242+
assert(tbig > 9464876000000);
243+
#endif
227244
}
228245

229246
void test_difftime() {

test/test_other.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5604,7 +5604,9 @@ def test_force_stdlibs(self):
56045604

56055605
@also_with_standalone_wasm(impure=True)
56065606
def test_time(self):
5607-
self.do_other_test('test_time.c')
5607+
if self.get_setting('STANDALONE_WASM'):
5608+
self.cflags.append('-DSTANDALONE')
5609+
self.do_other_test('test_time.c', cflags=['-sASSERTIONS=2'])
56085610

56095611
@parameterized({
56105612
'1': ('EST+05EDT',),

0 commit comments

Comments
 (0)