Fix cookies with far expiration date.

Some websites set cookies expiring in the (not so) far future, after year 2038.
So, using time_t to store the cookie expiration date won't do. Use the
BDateTime class instead.

This makes goodsearch.com login work again (#10460).
This commit is contained in:
Adrien Destugues
2014-01-23 17:22:46 +01:00
parent 281727261d
commit d417133ed2
3 changed files with 29 additions and 20 deletions
+5 -4
View File
@@ -7,6 +7,7 @@
#include <ctime> #include <ctime>
#include <DateTime.h>
#include <String.h> #include <String.h>
namespace BPrivate { namespace BPrivate {
@@ -24,21 +25,21 @@ enum {
class BHttpTime { class BHttpTime {
public: public:
BHttpTime(); BHttpTime();
BHttpTime(time_t date); BHttpTime(BDateTime date);
BHttpTime(const BString& dateString); BHttpTime(const BString& dateString);
// Date modification // Date modification
void SetString(const BString& string); void SetString(const BString& string);
void SetDate(time_t date); void SetDate(BDateTime date);
// Date conversion // Date conversion
time_t Parse(); BDateTime Parse();
BString ToString(int8 format = B_HTTP_TIME_FORMAT_PARSED); BString ToString(int8 format = B_HTTP_TIME_FORMAT_PARSED);
private: private:
BString fDateString; BString fDateString;
time_t fDate; BDateTime fDate;
int8 fDateFormat; int8 fDateFormat;
}; };
+21 -13
View File
@@ -13,9 +13,6 @@
#include <cstdio> #include <cstdio>
#define PRINT(x) printf x
static const char* kRfc1123Format = "%a, %d %b %Y %H:%M:%S GMT"; static const char* kRfc1123Format = "%a, %d %b %Y %H:%M:%S GMT";
static const char* kCookieFormat = "%a, %d-%b-%Y %H:%M:%S GMT"; static const char* kCookieFormat = "%a, %d-%b-%Y %H:%M:%S GMT";
static const char* kRfc1036Format = "%A, %d-%b-%y %H:%M:%S GMT"; static const char* kRfc1036Format = "%A, %d-%b-%y %H:%M:%S GMT";
@@ -33,7 +30,7 @@ BHttpTime::BHttpTime()
} }
BHttpTime::BHttpTime(time_t date) BHttpTime::BHttpTime(BDateTime date)
: :
fDate(date), fDate(date),
fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED) fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED)
@@ -61,7 +58,7 @@ BHttpTime::SetString(const BString& string)
void void
BHttpTime::SetDate(time_t date) BHttpTime::SetDate(BDateTime date)
{ {
fDate = date; fDate = date;
} }
@@ -70,7 +67,7 @@ BHttpTime::SetDate(time_t date)
// #pragma mark Date conversion // #pragma mark Date conversion
time_t BDateTime
BHttpTime::Parse() BHttpTime::Parse()
{ {
struct tm expireTime; struct tm expireTime;
@@ -109,9 +106,10 @@ BHttpTime::Parse()
// since Haiku does not appear to implement timegm(). // since Haiku does not appear to implement timegm().
// Using mktime() doesn't cut it, as cookies set with a date shortly in the // Using mktime() doesn't cut it, as cookies set with a date shortly in the
// future (eg. 1 hour) would expire immediately. // future (eg. 1 hour) would expire immediately.
time_t t = mktime(&expireTime); BTime time(expireTime.tm_hour, expireTime.tm_min, expireTime.tm_sec);
t -= mktime(gmtime(&t)) - (int)mktime(localtime(&t)); BDate date(expireTime.tm_year, expireTime.tm_mon, expireTime.tm_mday);
return t; BDateTime dateTime(date, time);
return dateTime;
} }
@@ -119,7 +117,17 @@ BString
BHttpTime::ToString(int8 format) BHttpTime::ToString(int8 format)
{ {
BString expirationFinal; BString expirationFinal;
struct tm* expirationTm = localtime(&fDate); struct tm expirationTm;
expirationTm.tm_sec = fDate.Time().Second();
expirationTm.tm_min = fDate.Time().Minute();
expirationTm.tm_hour = fDate.Time().Hour();
expirationTm.tm_mday = fDate.Date().Day();
expirationTm.tm_mon = fDate.Date().Month();
expirationTm.tm_year = fDate.Date().Day();
expirationTm.tm_wday = 0;
expirationTm.tm_yday = 0;
expirationTm.tm_isdst = 0;
char expirationString[kTimetToStringMaxLength + 1]; char expirationString[kTimetToStringMaxLength + 1];
size_t strLength; size_t strLength;
@@ -127,17 +135,17 @@ BHttpTime::ToString(int8 format)
default: default:
case B_HTTP_TIME_FORMAT_RFC1123: case B_HTTP_TIME_FORMAT_RFC1123:
strLength = strftime(expirationString, kTimetToStringMaxLength, strLength = strftime(expirationString, kTimetToStringMaxLength,
kRfc1123Format, expirationTm); kRfc1123Format, &expirationTm);
break; break;
case B_HTTP_TIME_FORMAT_RFC1036: case B_HTTP_TIME_FORMAT_RFC1036:
strLength = strftime(expirationString, kTimetToStringMaxLength, strLength = strftime(expirationString, kTimetToStringMaxLength,
kRfc1036Format, expirationTm); kRfc1036Format, &expirationTm);
break; break;
case B_HTTP_TIME_FORMAT_ASCTIME: case B_HTTP_TIME_FORMAT_ASCTIME:
strLength = strftime(expirationString, kTimetToStringMaxLength, strLength = strftime(expirationString, kTimetToStringMaxLength,
kAscTimeFormat, expirationTm); kAscTimeFormat, &expirationTm);
break; break;
} }
+3 -3
View File
@@ -157,8 +157,8 @@ BNetworkCookie::ParseCookieString(const BString& string, const BUrl& url)
result = B_BAD_VALUE; result = B_BAD_VALUE;
continue; continue;
} }
BHttpTime date(value); BDateTime parsed = BHttpTime(value).Parse();
SetExpirationDate(date.Parse()); SetExpirationDate(parsed);
} else if (name.ICompare("domain") == 0) { } else if (name.ICompare("domain") == 0) {
if (value.IsEmpty()) { if (value.IsEmpty()) {
result = B_BAD_VALUE; result = B_BAD_VALUE;
@@ -350,7 +350,7 @@ BNetworkCookie::ExpirationDate() const
const BString& const BString&
BNetworkCookie::ExpirationString() const BNetworkCookie::ExpirationString() const
{ {
BHttpTime date(ExpirationDate()); BHttpTime date(fExpiration);
if (!fExpirationStringValid) { if (!fExpirationStringValid) {
fExpirationString = date.ToString(BPrivate::B_HTTP_TIME_FORMAT_COOKIE); fExpirationString = date.ToString(BPrivate::B_HTTP_TIME_FORMAT_COOKIE);