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
This commit is contained in:
Peter Harper 2025-04-11 17:14:26 +01:00 committed by GitHub
parent d47c0c89ce
commit f674850f0e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 43 additions and 0 deletions

View file

@ -63,6 +63,7 @@ void datetime_to_tm(const datetime_t *dt, struct tm *tm) {
tm->tm_hour = dt->hour;
tm->tm_min = dt->min;
tm->tm_sec = dt->sec;
tm->tm_isdst = -1;
}
void tm_to_datetime(const struct tm *tm, datetime_t *dt) {

View file

@ -85,6 +85,7 @@ static int issue_1953_test(void);
static int issue_2118_test(void);
static int issue_2148_test(void);
static int issue_2186_test(void);
static int issue_2374_test(void);
int main() {
setup_default_uart();
@ -263,6 +264,8 @@ int main() {
issue_2186_test();
issue_2374_test();
PICOTEST_END_TEST();
}
@ -421,3 +424,42 @@ static int issue_2148_test(void) {
#endif
return 0;
}
static void fill_stack(int val) {
uint8_t array[50];
memset(array, val, sizeof(array));
}
// aon_timer_get_time called aon_timer_get_time_calendar which called datetime_to_tm
// which didn't initialise tm_isdst
static int issue_2374_test(void) {
#if HAS_RP2040_RTC && !__clang__
PICOTEST_START_SECTION("Issue #2374 defect - time goes backwards");
setenv("TZ", "PST8PDT7,M3.2.0/2,M11.1.0/02:00:00", 1);
tzset();
struct timespec ts = { .tv_sec = 1743055938, .tv_nsec = 0 };
aon_timer_start(&ts);
struct timespec ts1;
fill_stack(1); // Setting tm_isdst if it's uninitialised
hard_assert(aon_timer_get_time(&ts1));
sleep_ms(1000);
struct timespec ts2;
fill_stack(0); // Setting tm_isdst if it's uninitialised
hard_assert(aon_timer_get_time(&ts2));
// Check time hasn't been adjusted due to dst
hard_assert(ts1.tv_sec == ts2.tv_sec - 1);
setenv("TZ", "", 1);
tzset();
aon_timer_stop();
PICOTEST_END_SECTION();
#endif
return 0;
}