File indexing completed on 2024-05-05 12:17:41
0001 /* 0002 This file is part of KDE 0003 0004 SPDX-FileCopyrightText: 2004 Waldo Bastian <bastian@kde.org> 0005 SPDX-FileCopyrightText: 2008 David Faure <faure@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only 0008 */ 0009 0010 #include <QDate> 0011 #include <QString> 0012 0013 #include <QStandardPaths> 0014 #include <QTest> 0015 #include <qplatformdefs.h> 0016 0017 #include "../../src/kioworkers/http/kcookiejar/kcookiejar.cpp" 0018 0019 static KCookieJar *jar; 0020 static QString *lastYear; 0021 static QString *nextYear; 0022 static KConfig *config = nullptr; 0023 static int windowId = 1234; // random number to be used as windowId for test cookies 0024 0025 static void popArg(QString &command, QString &line) 0026 { 0027 int i = line.indexOf(' '); 0028 if (i != -1) { 0029 command = line.left(i); 0030 line = line.mid(i + 1); 0031 } else { 0032 command = line; 0033 line.clear(); 0034 } 0035 } 0036 0037 static void clearConfig() 0038 { 0039 delete config; 0040 QString file = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + "kcookiejar-testconfig"; 0041 QFile::remove(file); 0042 config = new KConfig(file); 0043 KConfigGroup cg(config, "Cookie Policy"); 0044 cg.writeEntry("RejectCrossDomainCookies", false); 0045 cg.writeEntry("AcceptSessionCookies", false); 0046 cg.writeEntry("CookieGlobalAdvice", "Ask"); 0047 jar->loadConfig(config, false); 0048 } 0049 0050 static void clearCookies(bool sessionOnly = false) 0051 { 0052 if (sessionOnly) { 0053 jar->eatSessionCookies(windowId); 0054 } else { 0055 jar->eatAllCookies(); 0056 } 0057 } 0058 0059 static void saveCookies() 0060 { 0061 QString file = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + "kcookiejar-testcookies"; 0062 QFile::remove(file); 0063 jar->saveCookies(file); 0064 0065 // Add an empty domain to the cookies file, just for testing robustness 0066 QFile f(file); 0067 f.open(QIODevice::Append); 0068 f.write("[]\n \"\" \"/\" 1584320400 0 h 4 x\n"); 0069 f.close(); 0070 0071 delete jar; 0072 jar = new KCookieJar(); 0073 clearConfig(); 0074 jar->loadCookies(file); 0075 } 0076 0077 static void endSession() 0078 { 0079 jar->eatSessionCookies(windowId); 0080 } 0081 0082 static void processCookie(QString &line) 0083 { 0084 QString policy; 0085 popArg(policy, line); 0086 KCookieAdvice expectedAdvice = KCookieJar::strToAdvice(policy); 0087 if (expectedAdvice == KCookieDunno) { 0088 QFAIL(qPrintable(QStringLiteral("Unknown accept policy '%1'").arg(policy))); 0089 } 0090 0091 QString urlStr; 0092 popArg(urlStr, line); 0093 QUrl url(urlStr); 0094 if (!url.isValid()) { 0095 QFAIL(qPrintable(QStringLiteral("Invalid URL '%1'").arg(urlStr))); 0096 } 0097 if (url.isEmpty()) { 0098 QFAIL(qPrintable(QStringLiteral("Missing URL"))); 0099 } 0100 0101 line.replace(QLatin1String("%LASTYEAR%"), *lastYear); 0102 line.replace(QLatin1String("%NEXTYEAR%"), *nextYear); 0103 0104 KHttpCookieList list = jar->makeCookies(urlStr, line.toUtf8(), windowId); 0105 0106 if (list.isEmpty()) { 0107 QFAIL(qPrintable(QStringLiteral("Failed to make cookies from: '%1'").arg(line))); 0108 } 0109 0110 for (KHttpCookieList::iterator cookieIterator = list.begin(); cookieIterator != list.end(); ++cookieIterator) { 0111 KHttpCookie &cookie = *cookieIterator; 0112 const KCookieAdvice cookieAdvice = jar->cookieAdvice(cookie); 0113 if (cookieAdvice != expectedAdvice) { 0114 QFAIL(qPrintable(urlStr 0115 + QStringLiteral("\n'%2'\nGot advice '%3' expected '%4'") 0116 .arg(line, KCookieJar::adviceToStr(cookieAdvice), KCookieJar::adviceToStr(expectedAdvice)))); 0117 } 0118 jar->addCookie(cookie); 0119 } 0120 } 0121 0122 static void processCheck(QString &line) 0123 { 0124 QString urlStr; 0125 popArg(urlStr, line); 0126 QUrl url(urlStr); 0127 if (!url.isValid()) { 0128 QFAIL(qPrintable(QStringLiteral("Invalid URL '%1'").arg(urlStr))); 0129 } 0130 if (url.isEmpty()) { 0131 QFAIL(qPrintable(QStringLiteral("Missing URL"))); 0132 } 0133 0134 QString expectedCookies = line; 0135 0136 QString cookies = jar->findCookies(urlStr, false, windowId, nullptr).trimmed(); 0137 if (cookies != expectedCookies) { 0138 QFAIL(qPrintable(urlStr + QStringLiteral("\nGot '%1' expected '%2'").arg(cookies, expectedCookies))); 0139 } 0140 } 0141 0142 static void processClear(QString &line) 0143 { 0144 if (line == QLatin1String("CONFIG")) { 0145 clearConfig(); 0146 } else if (line == QLatin1String("COOKIES")) { 0147 clearCookies(); 0148 } else if (line == QLatin1String("SESSIONCOOKIES")) { 0149 clearCookies(true); 0150 } else { 0151 QFAIL(qPrintable(QStringLiteral("Unknown command 'CLEAR %1'").arg(line))); 0152 } 0153 } 0154 0155 static void processConfig(QString &line) 0156 { 0157 QString key; 0158 popArg(key, line); 0159 0160 if (key.isEmpty()) { 0161 QFAIL(qPrintable(QStringLiteral("Missing Key"))); 0162 } 0163 0164 KConfigGroup cg(config, "Cookie Policy"); 0165 cg.writeEntry(key, line); 0166 jar->loadConfig(config, false); 0167 } 0168 0169 static void processLine(QString line) 0170 { 0171 if (line.isEmpty()) { 0172 return; 0173 } 0174 0175 if (line[0] == '#') { 0176 if (line[1] == '#') { 0177 qDebug().noquote() << line; 0178 } 0179 return; 0180 } 0181 0182 QString command; 0183 popArg(command, line); 0184 if (command.isEmpty()) { 0185 return; 0186 } 0187 0188 if (command == QLatin1String("COOKIE")) { 0189 processCookie(line); 0190 } else if (command == QLatin1String("CHECK")) { 0191 processCheck(line); 0192 } else if (command == QLatin1String("CLEAR")) { 0193 processClear(line); 0194 } else if (command == QLatin1String("CONFIG")) { 0195 processConfig(line); 0196 } else if (command == QLatin1String("SAVE")) { 0197 saveCookies(); 0198 } else if (command == QLatin1String("ENDSESSION")) { 0199 endSession(); 0200 } else { 0201 QFAIL(qPrintable(QStringLiteral("Unknown command '%1'").arg(command))); 0202 } 0203 } 0204 0205 class KCookieJarTest : public QObject 0206 { 0207 Q_OBJECT 0208 private Q_SLOTS: 0209 void initTestCase() 0210 { 0211 QStandardPaths::setTestModeEnabled(true); 0212 jar = new KCookieJar; 0213 QDateTime dt = QDateTime::currentDateTime(); 0214 lastYear = new QString(dt.addYears(-1).toString(Qt::RFC2822Date)); 0215 nextYear = new QString(dt.addYears(1).toString(Qt::RFC2822Date)); 0216 } 0217 void testCookieFile_data() 0218 { 0219 QTest::addColumn<QString>("fileName"); 0220 QTest::newRow("cookie.test") << QFINDTESTDATA("cookie.test"); 0221 QTest::newRow("cookie_rfc.test") << QFINDTESTDATA("cookie_rfc.test"); 0222 QTest::newRow("cookie_saving.test") << QFINDTESTDATA("cookie_saving.test"); 0223 QTest::newRow("cookie_settings.test") << QFINDTESTDATA("cookie_settings.test"); 0224 QTest::newRow("cookie_session.test") << QFINDTESTDATA("cookie_session.test"); 0225 } 0226 void testCookieFile() 0227 { 0228 QFETCH(QString, fileName); 0229 clearConfig(); 0230 0231 QFile file(fileName); 0232 QVERIFY2(file.open(QIODevice::ReadOnly), qPrintable(fileName)); 0233 while (!file.atEnd()) { 0234 const QByteArray buf = file.readLine().chopped(1); 0235 processLine(QString::fromUtf8(buf)); 0236 } 0237 } 0238 0239 void testParseUrl_data() 0240 { 0241 QTest::addColumn<QString>("url"); 0242 QTest::addColumn<bool>("expectedResult"); 0243 QTest::addColumn<QString>("expectedFqdn"); 0244 QTest::addColumn<QString>("expectedPath"); 0245 QTest::newRow("empty") << "" << false << "" 0246 << ""; 0247 QTest::newRow("url with no path") << "http://bugs.kde.org" << true << "bugs.kde.org" 0248 << "/"; 0249 QTest::newRow("url with path") << "http://bugs.kde.org/foo" << true << "bugs.kde.org" 0250 << "/foo"; 0251 QTest::newRow("just a host") << "bugs.kde.org" << false << "" 0252 << ""; 0253 } 0254 void testParseUrl() 0255 { 0256 QFETCH(QString, url); 0257 QFETCH(bool, expectedResult); 0258 QFETCH(QString, expectedFqdn); 0259 QFETCH(QString, expectedPath); 0260 QString fqdn; 0261 QString path; 0262 bool result = KCookieJar::parseUrl(url, fqdn, path); 0263 QCOMPARE(result, expectedResult); 0264 QCOMPARE(fqdn, expectedFqdn); 0265 QCOMPARE(path, expectedPath); 0266 } 0267 0268 void testExtractDomains_data() 0269 { 0270 QTest::addColumn<QString>("fqdn"); 0271 QTest::addColumn<QStringList>("expectedDomains"); 0272 QTest::newRow("empty") << "" << (QStringList() << QStringLiteral("localhost")); 0273 QTest::newRow("ipv4") << "1.2.3.4" << (QStringList() << QStringLiteral("1.2.3.4")); 0274 QTest::newRow("ipv6") << "[fe80::213:d3ff:fef4:8c92]" << (QStringList() << QStringLiteral("[fe80::213:d3ff:fef4:8c92]")); 0275 QTest::newRow("bugs.kde.org") << "bugs.kde.org" 0276 << (QStringList() << QStringLiteral("bugs.kde.org") << QStringLiteral(".bugs.kde.org") << QStringLiteral("kde.org") 0277 << QStringLiteral(".kde.org")); 0278 } 0279 void testExtractDomains() 0280 { 0281 QFETCH(QString, fqdn); 0282 QFETCH(QStringList, expectedDomains); 0283 KCookieJar jar; 0284 QStringList lst; 0285 jar.extractDomains(fqdn, lst); 0286 QCOMPARE(lst, expectedDomains); 0287 } 0288 }; 0289 0290 QTEST_MAIN(KCookieJarTest) 0291 0292 #include "kcookiejartest.moc"