From kde-core-devel Sun Dec 13 14:30:30 2009 From: "Dawit A." Date: Sun, 13 Dec 2009 14:30:30 +0000 To: kde-core-devel Subject: Fix for KCookieJar's Year 2038 (Y2K38) problem... Message-Id: <200912130930.30891.adawit () kde ! org> X-MARC-Message: https://marc.info/?l=kde-core-devel&m=126071469307860 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--Boundary-00=_GqPJLDCb47mM70W" --Boundary-00=_GqPJLDCb47mM70W Content-Type: multipart/alternative; boundary="Boundary-01=_GqPJLamWmg2kHtu" Content-Transfer-Encoding: 7bit --Boundary-01=_GqPJLamWmg2kHtu Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi all, The attached patch is a fix for the so called Y2K38 (Year 2038) problem in kcookiejar due to the use of a 32-bit time_t variable to store the expiration date. Currently, if any site sets a cookie expiration date greater than 03:14:07 Tuesday, 19 January 2038, then the cookie will simply be deleted by kcookiejar because the 32-bit overflow will "wrap-around" its expiration date to be set in the past... --Boundary-01=_GqPJLamWmg2kHtu Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: 7bit

Hi all,

The attached patch is a fix for the so called Y2K38 (Year 2038) problem in kcookiejar due to the use of a 32-bit time_t variable to store the expiration date. Currently, if any site sets a cookie expiration date greater than 03:14:07 Tuesday, 19 January 2038, then the cookie will simply be deleted by kcookiejar because the 32-bit overflow will "wrap-around" its expiration date to be set in the past...

--Boundary-01=_GqPJLamWmg2kHtu-- --Boundary-00=_GqPJLDCb47mM70W Content-Type: text/x-patch; charset="UTF-8"; name="kcookiejar_y238k_fix_43branch.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kcookiejar_y238k_fix_43branch.patch" Index: kdelibs/kioslave/http/kcookiejar/kcookiewin.cpp =================================================================== --- kdelibs/kioslave/http/kcookiejar/kcookiewin.cpp (revision 1059052) +++ kdelibs/kioslave/http/kcookiejar/kcookiewin.cpp (working copy) @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -53,6 +52,7 @@ #include #include #include +#include KCookieWin::KCookieWin( QWidget *parent, KHttpCookieList cookieList, int defaultButton, bool showDetails ) @@ -284,7 +284,7 @@ else m_domain->setText(cookie.domain()); m_path->setText(cookie.path()); - QDateTime cookiedate; + KDateTime cookiedate; cookiedate.setTime_t(cookie.expireDate()); if (cookie.expireDate()) m_expires->setText(KGlobal::locale()->formatDateTime(cookiedate)); Index: kdelibs/kioslave/http/kcookiejar/tests/cookie.test =================================================================== --- kdelibs/kioslave/http/kcookiejar/tests/cookie.test (revision 1059052) +++ kdelibs/kioslave/http/kcookiejar/tests/cookie.test (working copy) @@ -160,3 +160,8 @@ CHECK https://192.168.0.1 Cookie: name1=value1; name11=value11; name3=value3 CHECK http://192.168.0.10 CHECK http://192.168.0 +## Check expiration dates for the so called Y2K38 (Year 2038) problem +COOKIE ASK http://foo.bar Set-Cookie: CFID=15727;expires=Tue, 06-Dec-2039 00:30:42 GMT;path=/ +COOKIE ASK http://foo.bar Set-Cookie: CFTOKEN=49898422;expires=Tue, 06-Dec-2039 00:30:42 GMT;path=/ +CHECK http://foo.bar Cookie: CFID=15727; CFTOKEN=49898422 +CLEAR COOKIES Index: kdelibs/kioslave/http/kcookiejar/kcookiejar.cpp =================================================================== --- kdelibs/kioslave/http/kcookiejar/kcookiejar.cpp (revision 1059052) +++ kdelibs/kioslave/http/kcookiejar/kcookiejar.cpp (working copy) @@ -129,7 +129,7 @@ const QString &_path, const QString &_name, const QString &_value, - time_t _expireDate, + qint64 _expireDate, int _protocolVersion, bool _secure, bool _httpOnly, @@ -150,7 +150,7 @@ // // Checks if a cookie has been expired // -bool KHttpCookie::isExpired(time_t currentDate) const +bool KHttpCookie::isExpired(qint64 currentDate) const { return (mExpireDate != 0) && (mExpireDate < currentDate); } @@ -722,7 +722,7 @@ // Insert cookie in chain cookieList.append(cookie); - lastCookie = cookieList.end(); --lastCookie; + lastCookie = cookieList.end(); --lastCookie; } else if (strncasecmp(cookieStr, "Set-Cookie2:", 12) == 0) { @@ -1246,7 +1246,7 @@ QTextStream ts(&saveFile); - time_t curTime = time(0); + qint64 curTime = time(0); ts << "# KDE Cookie File v2\n#\n"; @@ -1283,9 +1283,9 @@ domain += cookie.domain(); domain += '"'; // TODO: replace with direct QTextStream output ? - s.sprintf("%-20s %-20s %-12s %10lu %3d %-20s %-4i %s\n", + s.sprintf("%-20s %-20s %-12s %10lld %3d %-20s %-4i %s\n", cookie.host().toLatin1().constData(), domain.toLatin1().constData(), - path.toLatin1().constData(), (unsigned long) cookie.expireDate(), + path.toLatin1().constData(), cookie.expireDate(), cookie.protocolVersion(), cookie.name().isEmpty() ? cookie.value().toLatin1().constData() : cookie.name().toLatin1().constData(), (cookie.isSecure() ? 1 : 0) + (cookie.isHttpOnly() ? 2 : 0) + @@ -1342,7 +1342,7 @@ return false; } - time_t curTime = time(0); + qint64 curTime = time(0); char *buffer = new char[READ_BUFFER_SIZE]; @@ -1378,7 +1378,7 @@ const QString path = QString::fromLatin1( parseField(line) ); const QString expStr = QString::fromLatin1( parseField(line) ); if (expStr.isEmpty()) continue; - const int expDate = expStr.toInt(); + const qint64 expDate = expStr.toLongLong(); const QString verStr = QString::fromLatin1( parseField(line) ); if (verStr.isEmpty()) continue; int protVer = verStr.toInt(); Index: kdelibs/kioslave/http/kcookiejar/kcookiejar.h =================================================================== --- kdelibs/kioslave/http/kcookiejar/kcookiejar.h (revision 1059052) +++ kdelibs/kioslave/http/kcookiejar/kcookiejar.h (working copy) @@ -58,7 +58,7 @@ QString mPath; QString mName; QString mValue; - time_t mExpireDate; + qint64 mExpireDate; int mProtocolVersion; bool mSecure; bool mCrossDomain; @@ -74,7 +74,7 @@ const QString &_path=QString(), const QString &_name=QString(), const QString &_value=QString(), - time_t _expireDate=0, + qint64 _expireDate=0, int _protocolVersion=0, bool _secure = false, bool _httpOnly = false, @@ -88,10 +88,10 @@ QList &windowIds() { return mWindowIds; } const QList &windowIds() const { return mWindowIds; } void fixDomain(const QString &domain) { mDomain = domain; } - time_t expireDate() const { return mExpireDate; } + qint64 expireDate() const { return mExpireDate; } int protocolVersion() const { return mProtocolVersion; } bool isSecure() const { return mSecure; } - bool isExpired(time_t currentDate) const; + bool isExpired(qint64 currentDate) const; bool isCrossDomain() const { return mCrossDomain; } bool isHttpOnly() const { return mHttpOnly; } bool hasExplicitPath() const { return mExplicitPath; } Index: kdebase/apps/konqueror/settings/kio/kcookiesmanagement.cpp =================================================================== --- kdebase/apps/konqueror/settings/kio/kcookiesmanagement.cpp (revision 1059228) +++ kdebase/apps/konqueror/settings/kio/kcookiesmanagement.cpp (working copy) @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -46,6 +45,7 @@ #include #include #include +#include // Local #include "kcookiesmain.h" @@ -335,13 +335,13 @@ if (c == fieldVal.end()) // empty list, do not crash return false; cookie->value = *c++; - unsigned tmp = (*c++).toUInt(); + qint64 tmp = (*c++).toLongLong(); if( tmp == 0 ) cookie->expireDate = i18n("End of session"); else { - QDateTime expDate; + KDateTime expDate; expDate.setTime_t(tmp); cookie->expireDate = KGlobal::locale()->formatDateTime(expDate); } --Boundary-00=_GqPJLDCb47mM70W Content-Type: text/x-patch; charset="UTF-8"; name="kcookiejar_y238k_fix_trunk.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kcookiejar_y238k_fix_trunk.patch" Index: kdelibs/kioslave/http/kcookiejar/kcookiewin.cpp =================================================================== --- kdelibs/kioslave/http/kcookiejar/kcookiewin.cpp (revision 1061998) +++ kdelibs/kioslave/http/kcookiejar/kcookiewin.cpp (working copy) @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -52,6 +51,7 @@ #include #include #include +#include KCookieWin::KCookieWin( QWidget *parent, KHttpCookieList cookieList, int defaultButton, bool showDetails ) @@ -283,7 +283,7 @@ else m_domain->setText(cookie.domain()); m_path->setText(cookie.path()); - QDateTime cookiedate; + KDateTime cookiedate; cookiedate.setTime_t(cookie.expireDate()); if (cookie.expireDate()) m_expires->setText(KGlobal::locale()->formatDateTime(cookiedate)); Index: kdelibs/kioslave/http/kcookiejar/kcookiejar.cpp =================================================================== --- kdelibs/kioslave/http/kcookiejar/kcookiejar.cpp (revision 1061998) +++ kdelibs/kioslave/http/kcookiejar/kcookiejar.cpp (working copy) @@ -129,7 +129,7 @@ const QString &_path, const QString &_name, const QString &_value, - time_t _expireDate, + qint64 _expireDate, int _protocolVersion, bool _secure, bool _httpOnly, @@ -150,7 +150,7 @@ // // Checks if a cookie has been expired // -bool KHttpCookie::isExpired(time_t currentDate) const +bool KHttpCookie::isExpired(qint64 currentDate) const { return (mExpireDate != 0) && (mExpireDate < currentDate); } @@ -722,7 +722,7 @@ // Insert cookie in chain cookieList.append(cookie); - lastCookie = cookieList.end(); --lastCookie; + lastCookie = cookieList.end(); --lastCookie; } else if (strncasecmp(cookieStr, "Set-Cookie2:", 12) == 0) { @@ -1246,7 +1246,7 @@ QTextStream ts(&saveFile); - time_t curTime = time(0); + qint64 curTime = time(0); ts << "# KDE Cookie File v2\n#\n"; @@ -1283,9 +1283,9 @@ domain += cookie.domain(); domain += '"'; // TODO: replace with direct QTextStream output ? - s.sprintf("%-20s %-20s %-12s %10lu %3d %-20s %-4i %s\n", + s.sprintf("%-20s %-20s %-12s %10lld %3d %-20s %-4i %s\n", cookie.host().toLatin1().constData(), domain.toLatin1().constData(), - path.toLatin1().constData(), (unsigned long) cookie.expireDate(), + path.toLatin1().constData(), cookie.expireDate(), cookie.protocolVersion(), cookie.name().isEmpty() ? cookie.value().toLatin1().constData() : cookie.name().toLatin1().constData(), (cookie.isSecure() ? 1 : 0) + (cookie.isHttpOnly() ? 2 : 0) + @@ -1342,7 +1342,7 @@ return false; } - time_t curTime = time(0); + qint64 curTime = time(0); char *buffer = new char[READ_BUFFER_SIZE]; @@ -1378,7 +1378,7 @@ const QString path = QString::fromLatin1( parseField(line) ); const QString expStr = QString::fromLatin1( parseField(line) ); if (expStr.isEmpty()) continue; - const int expDate = expStr.toInt(); + const qint64 expDate = expStr.toLongLong(); const QString verStr = QString::fromLatin1( parseField(line) ); if (verStr.isEmpty()) continue; int protVer = verStr.toInt(); Index: kdelibs/kioslave/http/kcookiejar/tests/cookie.test =================================================================== --- kdelibs/kioslave/http/kcookiejar/tests/cookie.test (revision 1061998) +++ kdelibs/kioslave/http/kcookiejar/tests/cookie.test (working copy) @@ -160,3 +160,8 @@ CHECK https://192.168.0.1 Cookie: name1=value1; name11=value11; name3=value3 CHECK http://192.168.0.10 CHECK http://192.168.0 +## Check expiration dates for the so called Y2K38 (Year 2038) problem +COOKIE ASK http://foo.bar Set-Cookie: CFID=15727;expires=Tue, 06-Dec-2039 00:30:42 GMT;path=/ +COOKIE ASK http://foo.bar Set-Cookie: CFTOKEN=49898422;expires=Tue, 06-Dec-2039 00:30:42 GMT;path=/ +CHECK http://foo.bar Cookie: CFID=15727; CFTOKEN=49898422 +CLEAR COOKIES Index: kdelibs/kioslave/http/kcookiejar/kcookiejar.h =================================================================== --- kdelibs/kioslave/http/kcookiejar/kcookiejar.h (revision 1061998) +++ kdelibs/kioslave/http/kcookiejar/kcookiejar.h (working copy) @@ -58,7 +58,7 @@ QString mPath; QString mName; QString mValue; - time_t mExpireDate; + qint64 mExpireDate; int mProtocolVersion; bool mSecure; bool mCrossDomain; @@ -74,7 +74,7 @@ const QString &_path=QString(), const QString &_name=QString(), const QString &_value=QString(), - time_t _expireDate=0, + qint64 _expireDate=0, int _protocolVersion=0, bool _secure = false, bool _httpOnly = false, @@ -88,10 +88,10 @@ QList &windowIds() { return mWindowIds; } const QList &windowIds() const { return mWindowIds; } void fixDomain(const QString &domain) { mDomain = domain; } - time_t expireDate() const { return mExpireDate; } + qint64 expireDate() const { return mExpireDate; } int protocolVersion() const { return mProtocolVersion; } bool isSecure() const { return mSecure; } - bool isExpired(time_t currentDate) const; + bool isExpired(qint64 currentDate) const; bool isCrossDomain() const { return mCrossDomain; } bool isHttpOnly() const { return mHttpOnly; } bool hasExplicitPath() const { return mExplicitPath; } Index: kdebase/apps/konqueror/settings/kio/kcookiesmanagement.cpp =================================================================== --- kdebase/apps/konqueror/settings/kio/kcookiesmanagement.cpp (revision 1061997) +++ kdebase/apps/konqueror/settings/kio/kcookiesmanagement.cpp (working copy) @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -46,6 +45,7 @@ #include #include #include +#include // Local #include "kcookiesmain.h" @@ -336,13 +336,13 @@ if (c == fieldVal.end()) // empty list, do not crash return false; cookie->value = *c++; - unsigned tmp = (*c++).toUInt(); + qint64 tmp = (*c++).toLongLong(); if( tmp == 0 ) cookie->expireDate = i18n("End of session"); else { - QDateTime expDate; + KDateTime expDate; expDate.setTime_t(tmp); cookie->expireDate = KGlobal::locale()->formatDateTime(expDate); } --Boundary-00=_GqPJLDCb47mM70W--