]> git.sur5r.net Git - openldap/commitdiff
strptime is unreliable, just parse time ourselves
authorHoward Chu <hyc@openldap.org>
Sun, 18 Jul 2004 18:28:16 +0000 (18:28 +0000)
committerHoward Chu <hyc@openldap.org>
Sun, 18 Jul 2004 18:28:16 +0000 (18:28 +0000)
servers/slapd/overlays/ppolicy.c

index b458ab08076a8d3f1911cfdb30aaf81f267ea666..b146bce1609f0260c12b38f69255019ec72d11e9 100644 (file)
@@ -39,6 +39,7 @@
 #include <ac/errno.h>
 #include <ac/time.h>
 #include <ac/string.h>
+#include <ac/ctype.h>
 
 #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