Skip to content

Commit f674850

Browse files
Fix DST bug in aon_timer_get_time for rp2040 (#2409)
If you set the timezone, aon_timer_get_time can wrongly apply a daylight saving time adjustment based on the stack contents. This can make it appear that time has gone backwards. Make sure datetime_to_tm initialises tm_isdst to -1. Fixes #2374
1 parent d47c0c8 commit f674850

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

src/common/pico_util/datetime.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ void datetime_to_tm(const datetime_t *dt, struct tm *tm) {
6363
tm->tm_hour = dt->hour;
6464
tm->tm_min = dt->min;
6565
tm->tm_sec = dt->sec;
66+
tm->tm_isdst = -1;
6667
}
6768

6869
void tm_to_datetime(const struct tm *tm, datetime_t *dt) {

test/pico_time_test/pico_time_test.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static int issue_1953_test(void);
8585
static int issue_2118_test(void);
8686
static int issue_2148_test(void);
8787
static int issue_2186_test(void);
88+
static int issue_2374_test(void);
8889

8990
int main() {
9091
setup_default_uart();
@@ -263,6 +264,8 @@ int main() {
263264

264265
issue_2186_test();
265266

267+
issue_2374_test();
268+
266269
PICOTEST_END_TEST();
267270
}
268271

@@ -421,3 +424,42 @@ static int issue_2148_test(void) {
421424
#endif
422425
return 0;
423426
}
427+
428+
static void fill_stack(int val) {
429+
uint8_t array[50];
430+
memset(array, val, sizeof(array));
431+
}
432+
433+
// aon_timer_get_time called aon_timer_get_time_calendar which called datetime_to_tm
434+
// which didn't initialise tm_isdst
435+
static int issue_2374_test(void) {
436+
#if HAS_RP2040_RTC && !__clang__
437+
PICOTEST_START_SECTION("Issue #2374 defect - time goes backwards");
438+
setenv("TZ", "PST8PDT7,M3.2.0/2,M11.1.0/02:00:00", 1);
439+
tzset();
440+
441+
struct timespec ts = { .tv_sec = 1743055938, .tv_nsec = 0 };
442+
aon_timer_start(&ts);
443+
444+
struct timespec ts1;
445+
fill_stack(1); // Setting tm_isdst if it's uninitialised
446+
hard_assert(aon_timer_get_time(&ts1));
447+
448+
sleep_ms(1000);
449+
450+
struct timespec ts2;
451+
fill_stack(0); // Setting tm_isdst if it's uninitialised
452+
hard_assert(aon_timer_get_time(&ts2));
453+
454+
// Check time hasn't been adjusted due to dst
455+
hard_assert(ts1.tv_sec == ts2.tv_sec - 1);
456+
457+
setenv("TZ", "", 1);
458+
tzset();
459+
460+
aon_timer_stop();
461+
462+
PICOTEST_END_SECTION();
463+
#endif
464+
return 0;
465+
}

0 commit comments

Comments
 (0)