--- httplint/httplint.c 2003/12/17 17:44:40 41 +++ httplint/httplint.c 2003/12/18 00:52:50 44 @@ -49,6 +49,7 @@ void check_header(const char *name, const char *value); bool parse_date(const char *s, struct tm *tm); int month(const char *s); +time_t mktime_from_utc(struct tm *t); const char *skip_lws(const char *s); bool parse_list(const char *s, regex_t *preg, unsigned int n, unsigned int m, void (*callback)(const char *s, regmatch_t pmatch[])); @@ -176,10 +177,10 @@ "^HTTP/([0-9]+)[.]([0-9]+) ([0-9][0-9][0-9]) ([\t -~€-ÿ]*)$", REG_EXTENDED); regcomp_wrapper(&re_token, - "^([-0-9a-zA-Z_.]+)", + "^([-0-9a-zA-Z_.!]+)", REG_EXTENDED); regcomp_wrapper(&re_token_value, - "^([-0-9a-zA-Z_.]+)(=([-0-9a-zA-Z_.]+|\"([^\"]|[\\].)*\"))?", + "^([-0-9a-zA-Z_.!]+)(=([-0-9a-zA-Z_.!]+|\"([^\"]|[\\].)*\"))?", REG_EXTENDED); regcomp_wrapper(&re_content_type, "^([-0-9a-zA-Z_.]+)/([-0-9a-zA-Z_.]+)[ \t]*" @@ -193,7 +194,7 @@ "^(W/[ \t]*)?\"([^\"]|[\\].)*\"$", REG_EXTENDED); regcomp_wrapper(&re_server, - "^((([-0-9a-zA-Z_.]+(/[-0-9a-zA-Z_.]+)?)|(\\(.*\\)))[ \t]*)+$", + "^((([-0-9a-zA-Z_.!]+(/[-0-9a-zA-Z_.]+)?)|(\\(.*\\)))[ \t]*)+$", REG_EXTENDED); regcomp_wrapper(&re_transfer_coding, "^([-0-9a-zA-Z_.]+)[ \t]*" @@ -204,7 +205,7 @@ "^([-0-9a-zA-Z_.](/[-0-9a-zA-Z_.])?)+$", REG_EXTENDED); regcomp_wrapper(&re_ugly, - "^[a-zA-Z0-9]+://[^/]+[/a-zA-Z0-9-_]*$", + "^[a-zA-Z0-9]+://[^/]+[-/a-zA-Z0-9_]*$", REG_EXTENDED); regcomp_wrapper(&re_rfc1123, "^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), ([0123][0-9]) " @@ -397,8 +398,11 @@ if (header) { header->count++; header->handler(value); - } else + } else if ((name[0] == 'X' || name[0] == 'x') && name[1] == '-') { + lookup("xheader"); + } else { lookup("nonstandard"); + } } @@ -411,12 +415,6 @@ int len = strlen(s); regmatch_t pmatch[20]; - tm->tm_wday = 0; - tm->tm_yday = 0; - tm->tm_isdst = 0; - tm->tm_gmtoff = 0; - tm->tm_zone = "GMT"; - if (len == 29) { /* RFC 1123 */ r = regexec(&re_rfc1123, s, 20, pmatch, 0); @@ -501,6 +499,39 @@ /** + * UTC version of mktime, from + * http://lists.debian.org/deity/2002/deity-200204/msg00082.html + */ +time_t mktime_from_utc(struct tm *t) +{ + time_t tl, tb; + struct tm *tg; + + tl = mktime (t); + if (tl == -1) + { + t->tm_hour--; + tl = mktime (t); + if (tl == -1) + return -1; /* can't deal with output from strptime */ + tl += 3600; + } + tg = gmtime (&tl); + tg->tm_isdst = 0; + tb = mktime (tg); + if (tb == -1) + { + tg->tm_hour--; + tb = mktime (tg); + if (tb == -1) + return -1; /* can't deal with output from gmtime */ + tb += 3600; + } + return (tl - (tb - tl)); +} + + +/** * Skip optional LWS (linear white space) [2.2] */ const char *skip_lws(const char *s) @@ -754,7 +785,7 @@ time0 = time(0); if (!parse_date(s, &tm)) return; - time1 = mktime(&tm); + time1 = mktime_from_utc(&tm); diff = difftime(time0, time1); if (10 < fabs(diff)) @@ -789,7 +820,7 @@ time0 = time(0); if (!parse_date(s, &tm)) return; - time1 = mktime(&tm); + time1 = mktime_from_utc(&tm); diff = difftime(time1, time0); if (10 < diff) @@ -1058,7 +1089,8 @@ { "via", "This header was added by a proxy, cache or gateway." }, { "wrongdate", "Warning: The server date-time differs from this system's " "date-time by more than 10 seconds. Check that both the " - "system clocks are correct." } + "system clocks are correct." }, + { "xheader", "This is an extension header. I don't know how to check it." } };