]> granicus.if.org Git - vnstat/commitdiff
fix bug in mosecs() that caused unintended shared pointer modification sometimes...
authorTeemu Toivola <git@humdi.net>
Thu, 15 Oct 2015 18:42:27 +0000 (21:42 +0300)
committerTeemu Toivola <git@humdi.net>
Thu, 15 Oct 2015 18:42:27 +0000 (21:42 +0300)
src/common.c
tests/common_tests.c

index cc7b7d4013337a742980cadba4da8fb95452a63b..44b9cc1f78d25cf6462cedbb89bc550de2885415 100644 (file)
@@ -151,23 +151,22 @@ int dmonth(int month)
 
 uint32_t mosecs(void)
 {
-       struct tm *d;
+       struct tm d;
+       extern long timezone;
 
-       d = localtime(&data.month[0].month);
-
-       if (d == NULL) {
+       if (localtime_r(&data.month[0].month, &d) == NULL) {
                return 0;
        }
 
-       if (d->tm_mday < cfg.monthrotate) {
+       if (d.tm_mday < cfg.monthrotate) {
                return 0;
        }
 
-       d->tm_mday = cfg.monthrotate;
-       d->tm_hour = d->tm_min = d->tm_sec = 0;
+       d.tm_mday = cfg.monthrotate;
+       d.tm_hour = d.tm_min = d.tm_sec = 0;
 
        if ((data.lastupdated-data.month[0].month)>0) {
-               return data.lastupdated-mktime(d);
+               return data.lastupdated-mktime(&d)+timezone;
        } else {
                return 0;
        }
index bca61c1e32f1b9dc46810721bfa798166b19594a..134fa9aa060fddf0eb82bec5b45e284dfa7bdc7f 100644 (file)
@@ -63,6 +63,43 @@ START_TEST(mosecs_return_values)
 }
 END_TEST
 
+START_TEST(mosecs_does_not_change_tz)
+{
+       extern long timezone;
+       long timezone_before_call;
+
+       tzset();
+       timezone_before_call = timezone;
+
+       initdb();
+       defaultcfg();
+       data.month[0].month = 0;
+       data.lastupdated = 1;
+       ck_assert_int_eq(cfg.monthrotate, 1);
+       mosecs();
+       ck_assert_int_eq(timezone_before_call, timezone);
+}
+END_TEST
+
+START_TEST(mosecs_does_not_change_struct_tm_pointer_content)
+{
+       struct tm *stm;
+       time_t current;
+
+       current = time(NULL);
+       stm = localtime(&current);
+
+       initdb();
+       defaultcfg();
+       data.month[0].month = 0;
+       data.lastupdated = 1;
+       ck_assert_int_eq(cfg.monthrotate, 1);
+       ck_assert_int_eq(current, timelocal(stm));
+       ck_assert_int_eq((int)mosecs(), 1);
+       ck_assert_int_eq(current, timelocal(stm));
+}
+END_TEST
+
 START_TEST(countercalc_no_change)
 {
        uint64_t a, b;
@@ -338,6 +375,8 @@ void add_common_tests(Suite *s)
        tcase_add_test(tc_common, logprint_options);
        tcase_add_loop_test(tc_common, dmonth_return_within_range, 0, 12);
        tcase_add_test(tc_common, mosecs_return_values);
+       tcase_add_test(tc_common, mosecs_does_not_change_tz);
+       tcase_add_test(tc_common, mosecs_does_not_change_struct_tm_pointer_content);
        tcase_add_test(tc_common, countercalc_no_change);
        tcase_add_test(tc_common, countercalc_small_change);
        tcase_add_test(tc_common, countercalc_32bit);