@@ -556,22 +556,21 @@ char *TimeString(uint64_t msecStart, uint64_t msecEnd) {
556556
557557 if (msecStart ) {
558558 time_t secs = msecStart / 1000 ;
559- struct tm * tbuff = localtime ( & secs ) ;
560- if (!tbuff ) {
561- LogError ("localtime () error in %s line %d: %s" , __FILE__ , __LINE__ , strerror (errno ));
562- return "Error time convert " ;
559+ struct tm tbuff ;
560+ if (!localtime_r ( & secs , & tbuff ) ) {
561+ LogError ("localtime_r () error in %s line %d: %s" , __FILE__ , __LINE__ , strerror (errno ));
562+ return "0000-00-00 00:00:00 " ;
563563 }
564564 char t1 [64 ];
565- strftime (t1 , 63 , "%Y-%m-%d %H:%M:%S" , tbuff );
565+ strftime (t1 , 63 , "%Y-%m-%d %H:%M:%S" , & tbuff );
566566
567567 secs = msecEnd / 1000 ;
568- tbuff = localtime (& secs );
569- if (!tbuff ) {
570- LogError ("localtime() error in %s line %d: %s" , __FILE__ , __LINE__ , strerror (errno ));
571- return "Error time convert" ;
568+ if (!localtime_r (& secs , & tbuff )) {
569+ LogError ("localtime_r() error in %s line %d: %s" , __FILE__ , __LINE__ , strerror (errno ));
570+ return "0000-00-00 00:00:00" ;
572571 }
573572 char t2 [64 ];
574- strftime (t2 , 63 , "%Y-%m-%d %H:%M:%S" , tbuff );
573+ strftime (t2 , 63 , "%Y-%m-%d %H:%M:%S" , & tbuff );
575574
576575 snprintf (datestr , 254 , "%s.%03d - %s.%03d" , t1 , (int )(msecStart % 1000 ), t2 , (int )(msecEnd % 1000 ));
577576 } else {
@@ -582,87 +581,72 @@ char *TimeString(uint64_t msecStart, uint64_t msecEnd) {
582581}
583582
584583char * UNIX2ISO (time_t t ) {
585- struct tm * when ;
584+ struct tm when ;
586585 static char timestring [32 ];
587586
588- when = localtime (& t );
589- when -> tm_isdst = -1 ;
590- snprintf (timestring , 31 , "%4i%02i%02i%02i%02i%02i" , when -> tm_year + 1900 , when -> tm_mon + 1 , when -> tm_mday , when -> tm_hour , when -> tm_min ,
591- when -> tm_sec );
587+ localtime_r (& t , & when );
588+ when .tm_isdst = -1 ;
589+ snprintf (timestring , 31 , "%4i%02i%02i%02i%02i%02i" , when .tm_year + 1900 , when .tm_mon + 1 , when .tm_mday , when .tm_hour , when .tm_min , when .tm_sec );
592590 timestring [31 ] = '\0' ;
593591
594592 return timestring ;
595593
596594} // End of UNIX2ISO
597595
598- time_t ISO2UNIX (char * timestring ) {
599- char c , * p ;
600- struct tm when ;
601- time_t t ;
602-
603- // let localtime fill in all default fields such as summer time, TZ etc.
604- t = time (NULL );
605- localtime_r (& t , & when );
606- when .tm_sec = 0 ;
607- when .tm_wday = 0 ;
608- when .tm_yday = 0 ;
609- when .tm_isdst = -1 ;
596+ // convert yyyyMMddhhmm[ss] -> time_t
597+ time_t ISO2UNIX (const char * timestring ) {
598+ if (!timestring ) {
599+ LogError ("NULL time string" );
600+ return (time_t )- 1 ;
601+ }
610602
611603 size_t len = strlen (timestring );
612604 if (len != 12 && len != 14 ) {
613- LogError ("Wrong time format '%s'\n " , timestring );
614- return 0 ;
605+ LogError ("Wrong time format '%s'" , timestring );
606+ return ( time_t ) - 1 ;
615607 }
616- // 2019 05 05 12 00 (10)
617- // year
618- p = timestring ;
619- c = p [4 ];
620- p [4 ] = '\0' ;
621- when .tm_year = atoi (p ) - 1900 ;
622- p [4 ] = c ;
623-
624- // month
625- p += 4 ;
626- c = p [2 ];
627- p [2 ] = '\0' ;
628- when .tm_mon = atoi (p ) - 1 ;
629- p [2 ] = c ;
630-
631- // day
632- p += 2 ;
633- c = p [2 ];
634- p [2 ] = '\0' ;
635- when .tm_mday = atoi (p );
636- p [2 ] = c ;
637-
638- // hour
639- p += 2 ;
640- c = p [2 ];
641- p [2 ] = '\0' ;
642- when .tm_hour = atoi (p );
643- p [2 ] = c ;
644-
645- // minute
646- p += 2 ;
647- c = p [2 ];
648- p [2 ] = '\0' ;
649- when .tm_min = atoi (p );
650- p [2 ] = c ;
608+
609+ // ensure all characters are digits
610+ for (size_t i = 0 ; i < len ; i ++ ) {
611+ if (!isdigit ((unsigned char )timestring [i ])) {
612+ LogError ("Invalid character in time string '%s'" , timestring );
613+ return (time_t )- 1 ;
614+ }
615+ }
616+
617+ struct tm when = {0 };
618+
619+ // parse manually without modifying input
620+ when .tm_year = (timestring [0 ] - '0' ) * 1000 + (timestring [1 ] - '0' ) * 100 + (timestring [2 ] - '0' ) * 10 + (timestring [3 ] - '0' ) - 1900 ;
621+ when .tm_mon = ((timestring [4 ] - '0' ) * 10 + (timestring [5 ] - '0' )) - 1 ;
622+ when .tm_mday = (timestring [6 ] - '0' ) * 10 + (timestring [7 ] - '0' );
623+ when .tm_hour = (timestring [8 ] - '0' ) * 10 + (timestring [9 ] - '0' );
624+ when .tm_min = (timestring [10 ] - '0' ) * 10 + (timestring [11 ] - '0' );
625+ when .tm_sec = 0 ;
651626
652627 if (len == 14 ) {
653- p += 2 ;
654- when .tm_sec = atoi (p );
628+ when .tm_sec = (timestring [12 ] - '0' ) * 10 + (timestring [13 ] - '0' );
655629 }
656630
657- t = mktime (& when );
658- if (t == -1 ) {
659- LogError ("Failed to convert string '%s'\n" , timestring );
660- return 0 ;
661- } else {
662- // printf("%s %s", timestring, ctime(&t));
663- return t ;
631+ when .tm_isdst = -1 ; // let mktime determine DST
632+
633+ // range validation
634+ if (when .tm_mon < 0 || when .tm_mon > 11 || when .tm_mday < 1 || when .tm_mday > 31 || when .tm_hour < 0 || when .tm_hour > 23 || when .tm_min < 0 ||
635+ when .tm_min > 59 || when .tm_sec < 0 || when .tm_sec > 60 ) {
636+ LogError ("Out-of-range values in '%s'" , timestring );
637+ return (time_t )- 1 ;
638+ }
639+
640+ // comment
641+ // pthread_mutex_lock(&mktime_mutex);
642+ time_t t = mktime (& when );
643+ // pthread_mutex_unlock(&mktime_mutex);
644+ if (t == (time_t )- 1 ) {
645+ LogError ("Failed to convert string '%s'" , timestring );
646+ return (time_t )- 1 ;
664647 }
665648
649+ return t ;
666650} // End of ISO2UNIX
667651
668652long getTick (void ) {
0 commit comments