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:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user