Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Nov 2012 14:40:01 GMT
From:      Fabian Keil <fk@fabiankeil.de>
To:        freebsd-standards@FreeBSD.org
Subject:   Re: standards/173421: [patch] strptime() accepts formats that should be rejected
Message-ID:  <201211061440.qA6Ee1qx023155@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR standards/173421; it has been noted by GNATS.

From: Fabian Keil <fk@fabiankeil.de>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: standards/173421: [patch] strptime() accepts formats that
 should be rejected
Date: Tue, 6 Nov 2012 15:34:23 +0100

 --Sig_/YeAUBADYETtZpEjfu+USQD0
 Content-Type: multipart/mixed; boundary="MP_/6tB4BFU4RoWvX7WFBL_6Nfa"
 
 --MP_/6tB4BFU4RoWvX7WFBL_6Nfa
 Content-Type: text/plain; charset=US-ASCII
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: inline
 
 Attached is the test case.
 
 Usage:
 
 make strptime-test
 ./strptime-test
 
 Fabian
 
 --MP_/6tB4BFU4RoWvX7WFBL_6Nfa
 Content-Type: text/x-csrc
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: attachment; filename=strptime-test.c
 
 #include <string.h>
 #include <stdio.h>
 #include <time.h>
 #include <stdlib.h>
 #include <ctype.h>
 
 /** Calculates the number of elements in an array */
 #define SZ(X)  (sizeof(X) / sizeof(*X))
 
 /* Copied from Privoxy and somewhat modified */
 static int parse_header_time(const char *header_time, time_t *result)
 {
    struct tm gmt;
    /*
     * Checking for two-digit years first in an
     * attempt to work around GNU libc's strptime()
     * reporting negative year values when using %Y.
     */
    static const char time_formats[][22] =3D {
       /* Tue, 02-Jun-37 20:00:00 */
       "%a, %d-%b-%y %H:%M:%S",
       /* Tue, 02 Jun 2037 20:00:00 */
       "%a, %d %b %Y %H:%M:%S",
       /* Tue, 02-Jun-2037 20:00:00 */
       "%a, %d-%b-%Y %H:%M:%S",
       /* Tuesday, 02-Jun-2037 20:00:00 */
       "%A, %d-%b-%Y %H:%M:%S",
       /* Tuesday Jun 02 20:00:00 2037 */
       "%A %b %d %H:%M:%S %Y"
    };
    unsigned int i;
 
    for (i =3D 0; i < SZ(time_formats); i++)
    {
       memset(&gmt, 0, sizeof(gmt));
 
       if (NULL !=3D strptime(header_time, time_formats[i], &gmt))
       {
          /* Sanity check for GNU libc. */
          if (gmt.tm_year < 0)
          {
             printf("Failed to parse '%s' using '%s'. Moving on.\n",
                header_time, time_formats[i]);
             continue;
          }
 
          printf("Supposedly matching format: %s\n", time_formats[i]);
          *result =3D timegm(&gmt);
          return 0;
       }
    }
 
    return 1;
 
 }
 
 int main (void)
 {
    char buf[100];
    static const char date[] =3D "Thursday, 18-Oct-2012 00:11:22 GMT";
    struct tm *tm;
    time_t epoch;
    int failure;
 
    memset(&epoch, '\0', sizeof(epoch));
    if (parse_header_time(date, &epoch))
    {
       printf("No matching format string for: %s!\n", date);
       return 1;
    }
    tm =3D gmtime(&epoch);
    failure =3D (tm->tm_year + 1900 !=3D 2012);
    strftime(buf, sizeof(buf), "%A, %d-%b-%Y %H:%M:%S GMT", tm);
    printf("%s -> %s\n%s\n", date, buf, failure ? "fail" : "ok");
 
    return failure;
 }
 
 --MP_/6tB4BFU4RoWvX7WFBL_6Nfa--
 
 --Sig_/YeAUBADYETtZpEjfu+USQD0
 Content-Type: application/pgp-signature; name=signature.asc
 Content-Disposition: attachment; filename=signature.asc
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.19 (FreeBSD)
 
 iEYEARECAAYFAlCZH/MACgkQSMVSH78upWP9ogCdFe/4zpYQdkSuF0xI9peLyBPi
 y/AAnRfgjWbTrzrMf2SytoOpISvRBnmx
 =Uxsl
 -----END PGP SIGNATURE-----
 
 --Sig_/YeAUBADYETtZpEjfu+USQD0--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211061440.qA6Ee1qx023155>