summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2018-07-31 12:53:01 +0200
committerKonstantin Käfer <mail@kkaefer.com>2018-07-31 20:57:09 +0200
commitc77aa79f51702179032b681fef2df31399fcec4f (patch)
treed359b5859c58830954e65df19483555c09e729de
parent2c5bebbdd8a5fc16719145b06e5812851fdb8751 (diff)
downloadqtlocation-mapboxgl-c77aa79f51702179032b681fef2df31399fcec4f.tar.gz
[core] update parse_date from cURL 7.61.0
-rw-r--r--src/parsedate/parsedate.cpp201
-rw-r--r--src/parsedate/parsedate.hpp7
2 files changed, 100 insertions, 108 deletions
diff --git a/src/parsedate/parsedate.cpp b/src/parsedate/parsedate.cpp
index ff945589bb..3697693f9d 100644
--- a/src/parsedate/parsedate.cpp
+++ b/src/parsedate/parsedate.cpp
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -89,11 +89,6 @@ extern "C" {
#include <stdlib.h>
#include <stdio.h>
-
-#define ERRNO (errno)
-#define SET_ERRNO(x) (errno = (x))
-
-
/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
its behavior is altered by the current locale. */
char raw_toupper(char in)
@@ -156,16 +151,19 @@ char raw_toupper(char in)
}
/*
- * raw_equal() is for doing "raw" case insensitive strings. This is meant
- * to be locale independent and only compare strings we know are safe for
- * this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
- * some further explanation to why this function is necessary.
+ * strcasecompare() is for doing "raw" case insensitive strings. This is
+ * meant to be locale independent and only compare strings we know are safe
+ * for this. See
+ * https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for some
+ * further explanation to why this function is necessary.
*
* The function is capable of comparing a-z case insensitively even for
* non-ascii.
+ *
+ * @unittest: 1301
*/
-int raw_equal(const char *first, const char *second)
+int strcasecompare(const char *first, const char *second)
{
while(*first && *second) {
if(raw_toupper(*first) != raw_toupper(*second))
@@ -201,23 +199,25 @@ int raw_equal(const char *first, const char *second)
#endif
+#define TIME_T_MIN 0
+#define TIME_T_MAX INT_MAX
/*
** signed long to signed int
*/
-int clamp_to_int(long slnum)
+int curlx_sltosi(long slnum)
{
return slnum > INT_MAX ? INT_MAX : slnum < INT_MIN ? INT_MIN : (int)slnum;
}
-const char * const wkday[] =
+const char * const Curl_wkday[] =
{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
static const char * const weekday[] =
{ "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday" };
-const char * const month[]=
+const char * const Curl_month[]=
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
@@ -249,6 +249,7 @@ static int parsedate(const char *date, time_t *output);
#define tDAYZONE -60 /* offset for daylight savings time */
static const struct tzinfo tz[]= {
{"GMT", 0}, /* Greenwich Mean */
+ {"UT", 0}, /* Universal Time */
{"UTC", 0}, /* Universal (Coordinated) */
{"WET", 0}, /* Western European */
{"BST", 0 tDAYZONE}, /* British Summer */
@@ -295,20 +296,20 @@ static const struct tzinfo tz[]= {
RFC 1123) had their signs wrong. Here we use the correct signs to match
actual military usage.
*/
- {"A", +1 * 60}, /* Alpha */
- {"B", +2 * 60}, /* Bravo */
- {"C", +3 * 60}, /* Charlie */
- {"D", +4 * 60}, /* Delta */
- {"E", +5 * 60}, /* Echo */
- {"F", +6 * 60}, /* Foxtrot */
- {"G", +7 * 60}, /* Golf */
- {"H", +8 * 60}, /* Hotel */
- {"I", +9 * 60}, /* India */
+ {"A", 1 * 60}, /* Alpha */
+ {"B", 2 * 60}, /* Bravo */
+ {"C", 3 * 60}, /* Charlie */
+ {"D", 4 * 60}, /* Delta */
+ {"E", 5 * 60}, /* Echo */
+ {"F", 6 * 60}, /* Foxtrot */
+ {"G", 7 * 60}, /* Golf */
+ {"H", 8 * 60}, /* Hotel */
+ {"I", 9 * 60}, /* India */
/* "J", Juliet is not used as a timezone, to indicate the observer's local
time */
- {"K", +10 * 60}, /* Kilo */
- {"L", +11 * 60}, /* Lima */
- {"M", +12 * 60}, /* Mike */
+ {"K", 10 * 60}, /* Kilo */
+ {"L", 11 * 60}, /* Lima */
+ {"M", 12 * 60}, /* Mike */
{"N", -1 * 60}, /* November */
{"O", -2 * 60}, /* Oscar */
{"P", -3 * 60}, /* Papa */
@@ -333,14 +334,14 @@ static int checkday(const char *check, size_t len)
{
int i;
const char * const *what;
- bool found= FALSE;
+ bool found = FALSE;
if(len > 3)
what = &weekday[0];
else
- what = &wkday[0];
- for(i=0; i<7; i++) {
- if(raw_equal(check, what[0])) {
- found=TRUE;
+ what = &Curl_wkday[0];
+ for(i = 0; i<7; i++) {
+ if(strcasecompare(check, what[0])) {
+ found = TRUE;
break;
}
what++;
@@ -352,12 +353,12 @@ static int checkmonth(const char *check)
{
int i;
const char * const *what;
- bool found= FALSE;
+ bool found = FALSE;
- what = &month[0];
- for(i=0; i<12; i++) {
- if(raw_equal(check, what[0])) {
- found=TRUE;
+ what = &Curl_month[0];
+ for(i = 0; i<12; i++) {
+ if(strcasecompare(check, what[0])) {
+ found = TRUE;
break;
}
what++;
@@ -372,12 +373,12 @@ static int checktz(const char *check)
{
unsigned int i;
const struct tzinfo *what;
- bool found= FALSE;
+ bool found = FALSE;
what = tz;
- for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) {
- if(raw_equal(check, what->name)) {
- found=TRUE;
+ for(i = 0; i< sizeof(tz)/sizeof(tz[0]); i++) {
+ if(strcasecompare(check, what->name)) {
+ found = TRUE;
break;
}
what++;
@@ -406,26 +407,23 @@ struct my_tm {
int tm_hour;
int tm_mday;
int tm_mon;
- int tm_year;
+ int tm_year; /* full year */
};
/* struct tm to time since epoch in GMT time zone.
* This is similar to the standard mktime function but for GMT only, and
* doesn't suffer from the various bugs and portability problems that
* some systems' implementations have.
+ *
+ * Returns 0 on success, otherwise non-zero.
*/
-static time_t my_timegm(struct my_tm *tm)
+static void my_timegm(struct my_tm *tm, time_t *t)
{
static const int month_days_cumulative [12] =
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
int month_, year, leap_days;
- if(tm->tm_year < 70)
- /* we don't support years before 1970 as they will cause this function
- to return a negative value */
- return -1;
-
- year = tm->tm_year + 1900;
+ year = tm->tm_year;
month_ = tm->tm_mon;
if(month_ < 0) {
year += (11 - month_) / 12;
@@ -440,9 +438,9 @@ static time_t my_timegm(struct my_tm *tm)
leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400)
- (1969 / 4) + (1969 / 100) - (1969 / 400));
- return ((((time_t) (year - 1970) * 365
- + leap_days + month_days_cumulative [month_] + tm->tm_mday - 1) * 24
- + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec;
+ *t = ((((time_t) (year - 1970) * 365
+ + leap_days + month_days_cumulative[month_] + tm->tm_mday - 1) * 24
+ + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec;
}
/*
@@ -459,21 +457,21 @@ static time_t my_timegm(struct my_tm *tm)
static int parsedate(const char *date, time_t *output)
{
time_t t = 0;
- int wdaynum=-1; /* day of the week number, 0-6 (mon-sun) */
- int monnum=-1; /* month of the year number, 0-11 */
- int mdaynum=-1; /* day of month, 1 - 31 */
- int hournum=-1;
- int minnum=-1;
- int secnum=-1;
- int yearnum=-1;
- int tzoff=-1;
+ int wdaynum = -1; /* day of the week number, 0-6 (mon-sun) */
+ int monnum = -1; /* month of the year number, 0-11 */
+ int mdaynum = -1; /* day of month, 1 - 31 */
+ int hournum = -1;
+ int minnum = -1;
+ int secnum = -1;
+ int yearnum = -1;
+ int tzoff = -1;
struct my_tm tm;
enum assume dignext = DATE_MDAY;
const char *indate = date; /* save the original pointer */
int part = 0; /* max 6 parts */
while(*date && (part < 6)) {
- bool found=FALSE;
+ bool found = FALSE;
skip(&date);
@@ -514,15 +512,17 @@ static int parsedate(const char *date, time_t *output)
/* a digit */
int val;
char *end;
+ int len = 0;
if((secnum == -1) &&
- (3 == sscanf(date, "%02d:%02d:%02d", &hournum, &minnum, &secnum))) {
+ (3 == sscanf(date, "%02d:%02d:%02d%n",
+ &hournum, &minnum, &secnum, &len))) {
/* time stamp! */
- date += 8;
+ date += len;
}
else if((secnum == -1) &&
- (2 == sscanf(date, "%02d:%02d", &hournum, &minnum))) {
+ (2 == sscanf(date, "%02d:%02d%n", &hournum, &minnum, &len))) {
/* time stamp without seconds */
- date += 5;
+ date += len;
secnum = 0;
}
else {
@@ -530,12 +530,12 @@ static int parsedate(const char *date, time_t *output)
int error;
int old_errno;
- old_errno = ERRNO;
- SET_ERRNO(0);
+ old_errno = errno;
+ errno = 0;
lval = strtol(date, &end, 10);
- error = ERRNO;
- if(error != old_errno)
- SET_ERRNO(old_errno);
+ error = errno;
+ if(errno != old_errno)
+ errno = old_errno;
if(error)
return PARSEDATE_FAIL;
@@ -545,7 +545,7 @@ static int parsedate(const char *date, time_t *output)
return PARSEDATE_FAIL;
#endif
- val = clamp_to_int(lval);
+ val = curlx_sltosi(lval);
if((tzoff == -1) &&
((end - date) == 4) &&
@@ -564,7 +564,7 @@ static int parsedate(const char *date, time_t *output)
tzoff = (val/100 * 60 + val%100)*60;
/* the + and - prefix indicates the local time compared to GMT,
- this we need ther reversed math to get what we want */
+ this we need their reversed math to get what we want */
tzoff = date[-1]=='+'?-tzoff:tzoff;
}
@@ -590,7 +590,7 @@ static int parsedate(const char *date, time_t *output)
if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) {
yearnum = val;
found = TRUE;
- if(yearnum < 1900) {
+ if(yearnum < 100) {
if(yearnum > 70)
yearnum += 1900;
else
@@ -619,19 +619,18 @@ static int parsedate(const char *date, time_t *output)
/* lacks vital info, fail */
return PARSEDATE_FAIL;
-#if SIZEOF_TIME_T < 5
- /* 32 bit time_t can only hold dates to the beginning of 2038 */
- if(yearnum > 2037) {
- *output = 0x7fffffff;
- return PARSEDATE_LATER;
- }
-#endif
-
if(yearnum < 1970) {
- *output = 0;
+ /* only positive numbers cannot return earlier */
+ *output = TIME_T_MIN;
return PARSEDATE_SOONER;
}
+ /* a signed 32 bit time_t can only hold dates to the beginning of 2038 */
+ if(yearnum > 2037) {
+ *output = TIME_T_MAX;
+ return PARSEDATE_LATER;
+ }
+
if((mdaynum > 31) || (monnum > 11) ||
(hournum > 23) || (minnum > 59) || (secnum > 60))
return PARSEDATE_FAIL; /* clearly an illegal date */
@@ -641,29 +640,25 @@ static int parsedate(const char *date, time_t *output)
tm.tm_hour = hournum;
tm.tm_mday = mdaynum;
tm.tm_mon = monnum;
- tm.tm_year = yearnum - 1900;
+ tm.tm_year = yearnum;
- /* my_timegm() returns a time_t. time_t is often 32 bits, even on many
- architectures that feature 64 bit 'long'.
-
- Some systems have 64 bit time_t and deal with years beyond 2038. However,
- even on some of the systems with 64 bit time_t mktime() returns -1 for
- dates beyond 03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06)
+ /* my_timegm() returns a time_t. time_t is often 32 bits, sometimes even on
+ architectures that feature 64 bit 'long' but ultimately time_t is the
+ correct data type to use.
*/
- t = my_timegm(&tm);
-
- /* time zone adjust (cast t to int to compare to negative one) */
- if(-1 != (int)t) {
+ my_timegm(&tm, &t);
- /* Add the time zone diff between local time zone and GMT. */
- long delta = (long)(tzoff!=-1?tzoff:0);
+ /* Add the time zone diff between local time zone and GMT. */
+ if(tzoff == -1)
+ tzoff = 0;
- if((delta>0) && (t > LONG_MAX - delta))
- return -1; /* time_t overflow */
-
- t += delta;
+ if((tzoff > 0) && (t > TIME_T_MAX - tzoff)) {
+ *output = TIME_T_MAX;
+ return PARSEDATE_LATER; /* time_t overflow */
}
+ t += tzoff;
+
*output = t;
return PARSEDATE_OK;
@@ -674,10 +669,10 @@ time_t parse_date(const char *p)
time_t parsed = -1;
int rc = parsedate(p, &parsed);
- switch(rc) {
- case PARSEDATE_OK:
- case PARSEDATE_LATER:
- case PARSEDATE_SOONER:
+ if(rc == PARSEDATE_OK) {
+ if(parsed == -1)
+ /* avoid returning -1 for a working scenario */
+ parsed++;
return parsed;
}
/* everything else is fail */
diff --git a/src/parsedate/parsedate.hpp b/src/parsedate/parsedate.hpp
index 6905e361d4..40bfccb7a0 100644
--- a/src/parsedate/parsedate.hpp
+++ b/src/parsedate/parsedate.hpp
@@ -1,5 +1,4 @@
-#ifndef HEADER_PARSEDATE_H
-#define HEADER_PARSEDATE_H
+#pragma once
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -11,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -34,5 +33,3 @@ time_t parse_date(const char *p);
#ifdef __cplusplus
}
#endif
-
-#endif /* HEADER_PARSEDATE_H */