From: Howard Chu Date: Sun, 18 Jul 2004 18:28:16 +0000 (+0000) Subject: strptime is unreliable, just parse time ourselves X-Git-Tag: OPENDLAP_REL_ENG_2_2_MP~55 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=a14bda1df43ba9217b95db965d86e46eb0abc661;p=openldap strptime is unreliable, just parse time ourselves --- diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c index b458ab0807..b146bce160 100644 --- a/servers/slapd/overlays/ppolicy.c +++ b/servers/slapd/overlays/ppolicy.c @@ -39,6 +39,7 @@ #include #include #include +#include #ifndef MODULE_NAME_SZ #define MODULE_NAME_SZ 256 @@ -246,20 +247,74 @@ static time_t parse_time( char *atm ) { struct tm tm; + char *ptr = atm; + time_t ret = (time_t)-1; + int i = 0; - if (!atm) return (time_t)-1; + while (atm) { - /* - * special case - if the lowest allowable GeneralizedTime is here, return - * this is as zero time. Note: this might also be the case if the value stored - * is equivalent to the start of the epoch (ie, Jan 1, 1970 at midnight. - */ - if (strcmp(atm, "00000101000000Z") == 0) return (time_t)0; - /* - * else parse the time and return it's time_t value. - */ - strptime( atm, "%Y%m%d%H%M%SZ", &tm ); - return ppolicy_timegm( &tm ); + /* Is the stamp reasonbly long? */ + for (i=0; isdigit(atm[i]); i++); + if (i < sizeof("00000101000000")-1) + break; + + /* + * parse the time and return it's time_t value. + */ + /* 4 digit year to year - 1900 */ + tm.tm_year = *ptr++ - '0'; + tm.tm_year *= 10; tm.tm_year += *ptr++ - '0'; + tm.tm_year *= 10; tm.tm_year += *ptr++ - '0'; + tm.tm_year *= 10; tm.tm_year += *ptr++ - '0'; + tm.tm_year -= 1900; + /* month 01-12 to 0-11 */ + tm.tm_mon = *ptr++ - '0'; + tm.tm_mon *=10; tm.tm_mon += *ptr++ - '0'; + if (tm.tm_mon < 1 || tm.tm_mon > 12) break; + tm.tm_mon--; + + /* day of month 01-31 */ + tm.tm_mday = *ptr++ - '0'; + tm.tm_mday *=10; tm.tm_mday += *ptr++ - '0'; + if (tm.tm_mday < 1 || tm.tm_mday > 31) break; + + /* Hour 00-23 */ + tm.tm_hour = *ptr++ - '0'; + tm.tm_hour *=10; tm.tm_hour += *ptr++ - '0'; + if (tm.tm_hour < 0 || tm.tm_hour > 23) break; + + /* Minute 00-59 */ + tm.tm_min = *ptr++ - '0'; + tm.tm_min *=10; tm.tm_min += *ptr++ - '0'; + if (tm.tm_min < 0 || tm.tm_min > 59) break; + + /* Second 00-61 */ + tm.tm_sec = *ptr++ - '0'; + tm.tm_sec *=10; tm.tm_sec += *ptr++ - '0'; + if (tm.tm_sec < 0 || tm.tm_sec > 61) break; + + /* Fractions of seconds */ + for (i = 0;isdigit(*ptr);) { + i*=10; i+= *ptr++ - '0'; + } + + /* + * special case - if the lowest allowable GeneralizedTime is here, return + * this as zero time. Note: this might also be the case if the value stored + * is equivalent to the start of the epoch (ie, Jan 1, 1970 at midnight. + */ + if (strncmp(atm, "00000101000000", sizeof("00000101000000")-1) == 0 && + i == 0 ) break; + + /* Must be UTC */ + if (*ptr != 'Z') break; + + /* FIXME: we don't check precision smaller than seconds. */ + + ret = ppolicy_timegm( &tm ); + break; + } + return ret; } static int