File indexing completed on 2024-04-14 14:24:04

0001 /*
0002     SPDX-FileCopyrightText: 2002, 2003 David Faure <faure@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "kurifiltertest.h"
0008 
0009 #include <KConfigGroup>
0010 #include <KSharedConfig>
0011 #include <KUriFilter>
0012 #include <QLoggingCategory>
0013 
0014 #include <QDir>
0015 #include <QHostInfo>
0016 #include <QRegularExpression>
0017 #include <QtTestWidgets>
0018 
0019 #include <iostream>
0020 
0021 QTEST_MAIN(KUriFilterTest)
0022 
0023 static const char *const s_uritypes[] = {"NetProtocol", "LOCAL_FILE", "LOCAL_DIR", "EXECUTABLE", "HELP", "SHELL", "BLOCKED", "ERROR", "UNKNOWN"};
0024 static constexpr int s_noFiltering = -2;
0025 
0026 static void setupColumns()
0027 {
0028     QTest::addColumn<QString>("input");
0029     QTest::addColumn<QString>("expectedResult");
0030     QTest::addColumn<int>("expectedUriType");
0031     QTest::addColumn<QStringList>("list");
0032     QTest::addColumn<QString>("absPath");
0033     QTest::addColumn<bool>("checkForExecutables");
0034 }
0035 
0036 static void addRow(const char *input,
0037                    const QString &expectedResult = QString(),
0038                    int expectedUriType = -1,
0039                    const QStringList &list = QStringList(),
0040                    const QString &absPath = QString(),
0041                    bool checkForExecutables = true)
0042 {
0043     QTest::newRow(input) << input << expectedResult << expectedUriType << list << absPath << checkForExecutables;
0044 }
0045 
0046 static void runFilterTest(const QString &a,
0047                           const QString &expectedResult = nullptr,
0048                           int expectedUriType = -1,
0049                           const QStringList &list = QStringList(),
0050                           const QString &absPath = nullptr,
0051                           bool checkForExecutables = true)
0052 {
0053     KUriFilterData *filterData = new KUriFilterData;
0054     filterData->setData(a);
0055     filterData->setCheckForExecutables(checkForExecutables);
0056 
0057     if (!absPath.isEmpty()) {
0058         filterData->setAbsolutePath(absPath);
0059         qDebug() << "Filtering: " << a << " with absPath=" << absPath;
0060     } else {
0061         qDebug() << "Filtering: " << a;
0062     }
0063 
0064     if (KUriFilter::self()->filterUri(*filterData, list)) {
0065         if (expectedUriType == s_noFiltering) {
0066             qCritical() << a << "Did not expect filtering. Got" << filterData->uri();
0067             QVERIFY(expectedUriType != s_noFiltering); // fail the test
0068         }
0069 
0070         // Copied from minicli...
0071         QString cmd;
0072         QUrl uri = filterData->uri();
0073 
0074         if (uri.isLocalFile() && !uri.hasFragment() && !uri.hasQuery() && (filterData->uriType() != KUriFilterData::NetProtocol)) {
0075             cmd = uri.toLocalFile();
0076         } else {
0077             cmd = uri.url(QUrl::FullyEncoded);
0078         }
0079 
0080         switch (filterData->uriType()) {
0081         case KUriFilterData::LocalFile:
0082         case KUriFilterData::LocalDir:
0083             qDebug() << "*** Result: Local Resource =>  '" << filterData->uri().toLocalFile() << "'";
0084             break;
0085         case KUriFilterData::Help:
0086             qDebug() << "*** Result: Local Resource =>  '" << filterData->uri().url() << "'";
0087             break;
0088         case KUriFilterData::NetProtocol:
0089             qDebug() << "*** Result: Network Resource => '" << filterData->uri().url() << "'";
0090             break;
0091         case KUriFilterData::Shell:
0092         case KUriFilterData::Executable:
0093             if (filterData->hasArgsAndOptions()) {
0094                 cmd += filterData->argsAndOptions();
0095             }
0096             qDebug() << "*** Result: Executable/Shell => '" << cmd << "'";
0097             break;
0098         case KUriFilterData::Error:
0099             qDebug() << "*** Result: Encountered error => '" << cmd << "'";
0100             qDebug() << "Reason:" << filterData->errorMsg();
0101             break;
0102         default:
0103             qDebug() << "*** Result: Unknown or invalid resource.";
0104         }
0105 
0106         if (!expectedResult.isEmpty()) {
0107             // Hack for other locales than english, normalize google hosts to google.com
0108             cmd.replace(QRegularExpression(QStringLiteral("www\\.google\\.[^/]*/")), QStringLiteral("www.google.com/"));
0109             if (cmd != expectedResult) {
0110                 qWarning() << a;
0111                 QCOMPARE(cmd, expectedResult);
0112             }
0113         }
0114 
0115         if (expectedUriType != -1 && expectedUriType != filterData->uriType()) {
0116             qWarning() << a << "Got URI type" << s_uritypes[filterData->uriType()] << "expected" << s_uritypes[expectedUriType];
0117             QCOMPARE(s_uritypes[filterData->uriType()], s_uritypes[expectedUriType]);
0118         }
0119     } else {
0120         if (expectedUriType == s_noFiltering) {
0121             qDebug() << "*** No filtering required.";
0122         } else {
0123             qDebug() << "*** Could not be filtered.";
0124             if (expectedUriType != filterData->uriType()) {
0125                 QCOMPARE(s_uritypes[filterData->uriType()], s_uritypes[expectedUriType]);
0126             }
0127         }
0128     }
0129 
0130     delete filterData;
0131     qDebug() << "-----";
0132 }
0133 
0134 static void runFilterTest()
0135 {
0136     QFETCH(QString, input);
0137     QFETCH(QString, expectedResult);
0138     QFETCH(int, expectedUriType);
0139     QFETCH(QStringList, list);
0140     QFETCH(QString, absPath);
0141     QFETCH(bool, checkForExecutables);
0142     runFilterTest(input, expectedResult, expectedUriType, list, absPath, checkForExecutables);
0143 }
0144 
0145 static void testLocalFile(const QString &filename)
0146 {
0147     QFile tmpFile(filename); // Yeah, I know, security risk blah blah. This is a test prog!
0148 
0149     if (tmpFile.open(QIODevice::ReadWrite)) {
0150         QByteArray fname = QFile::encodeName(tmpFile.fileName());
0151         runFilterTest(fname, fname, KUriFilterData::LocalFile);
0152         tmpFile.close();
0153         tmpFile.remove();
0154     } else {
0155         qDebug() << "Couldn't create " << tmpFile.fileName() << ", skipping test";
0156     }
0157 }
0158 
0159 static const char s_delimiter = WEBSHORTCUT_SEPARATOR;
0160 
0161 void KUriFilterTest::initTestCase()
0162 {
0163     QStandardPaths::setTestModeEnabled(true);
0164     minicliFilters << QStringLiteral("kshorturifilter") << QStringLiteral("kurisearchfilter") << QStringLiteral("localdomainurifilter");
0165     qtdir = qgetenv("QTDIR");
0166     home = qgetenv("HOME");
0167     qputenv("DATAHOME", QFile::encodeName(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)));
0168     datahome = qgetenv("DATAHOME");
0169     qDebug() << "libpaths" << QCoreApplication::libraryPaths();
0170 
0171     QLoggingCategory::setFilterRules(QStringLiteral("kf.kio.urifilters.*=true"));
0172 
0173     QString searchProvidersDir = QFINDTESTDATA("../src/urifilters/ikws/searchproviders/google.desktop").section('/', 0, -2);
0174     QVERIFY(!searchProvidersDir.isEmpty());
0175     qputenv("KIO_SEARCHPROVIDERS_DIR", QFile::encodeName(searchProvidersDir));
0176 
0177     // Many tests check the "default search engine" feature.
0178     // There is no default search engine by default (since it was annoying when making typos),
0179     // so the user has to set it up, which we do here.
0180     {
0181         KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("kuriikwsfilterrc"), KConfig::SimpleConfig), "General");
0182         cfg.writeEntry("DefaultWebShortcut", "google");
0183         cfg.writeEntry("KeywordDelimiter", QString(s_delimiter));
0184         cfg.sync();
0185     }
0186 
0187     // Copy kshorturifilterrc from the src dir so we don't depend on make install / env vars.
0188     {
0189         const QString rcFile = QFINDTESTDATA("../src/urifilters/shorturi/kshorturifilterrc");
0190         QVERIFY(!rcFile.isEmpty());
0191         const QString localFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kshorturifilterrc";
0192         QFile::remove(localFile);
0193         QVERIFY(QFile(rcFile).copy(localFile));
0194     }
0195 
0196     QDir().mkpath(datahome + QStringLiteral("/urifilter"));
0197 }
0198 
0199 void KUriFilterTest::pluginNames()
0200 {
0201     const QStringList plugins = KUriFilter::self()->pluginNames();
0202     qDebug() << plugins;
0203     const QByteArray debugString = plugins.join(',').toLatin1();
0204     // To make it possible to have external plugins (if there's any...)
0205     // we don't just have an expected result list, we just probe it for specific entries.
0206     QVERIFY2(plugins.contains("kshorturifilter"), debugString.constData());
0207     QVERIFY2(plugins.contains("kurisearchfilter"), debugString.constData());
0208     QVERIFY2(plugins.contains("localdomainurifilter"), debugString.constData());
0209     QVERIFY2(plugins.contains("fixhosturifilter"), debugString.constData());
0210     QVERIFY2(plugins.contains("kuriikwsfilter"), debugString.constData());
0211     // No duplicates
0212     QCOMPARE(plugins.count("kshorturifilter"), 1);
0213 }
0214 
0215 void KUriFilterTest::noFiltering_data()
0216 {
0217     setupColumns();
0218     // URI that should require no filtering
0219     addRow("http://www.kde.org", QStringLiteral("http://www.kde.org"), KUriFilterData::NetProtocol);
0220     // qtbase commit eaf4438b3511c preserves the double slashes
0221     addRow("http://www.kde.org/developer//index.html", QStringLiteral("http://www.kde.org/developer//index.html"), KUriFilterData::NetProtocol);
0222     addRow("file:///", QStringLiteral("/"), KUriFilterData::LocalDir);
0223     addRow("file:///etc", QStringLiteral("/etc"), KUriFilterData::LocalDir);
0224     addRow("file:///etc/passwd", QStringLiteral("/etc/passwd"), KUriFilterData::LocalFile);
0225 }
0226 
0227 void KUriFilterTest::noFiltering()
0228 {
0229     runFilterTest();
0230 }
0231 
0232 void KUriFilterTest::localFiles_data()
0233 {
0234     setupColumns();
0235     addRow("/", QStringLiteral("/"), KUriFilterData::LocalDir);
0236     addRow("/", QStringLiteral("/"), KUriFilterData::LocalDir, QStringList(QStringLiteral("kshorturifilter")));
0237     addRow("//", QStringLiteral("/"), KUriFilterData::LocalDir);
0238     addRow("///", QStringLiteral("/"), KUriFilterData::LocalDir);
0239     addRow("////", QStringLiteral("/"), KUriFilterData::LocalDir);
0240     addRow("///tmp", QStringLiteral("/tmp"), KUriFilterData::LocalDir);
0241     addRow("///tmp/", QStringLiteral("/tmp/"), KUriFilterData::LocalDir);
0242     addRow("///tmp//", QStringLiteral("/tmp/"), KUriFilterData::LocalDir);
0243     addRow("///tmp///", QStringLiteral("/tmp/"), KUriFilterData::LocalDir);
0244 
0245     if (QFile::exists(QDir::homePath() + QLatin1String("/.bashrc"))) {
0246         addRow("~/.bashrc", QDir::homePath() + QStringLiteral("/.bashrc"), KUriFilterData::LocalFile, QStringList(QStringLiteral("kshorturifilter")));
0247     }
0248     addRow("~", QDir::homePath(), KUriFilterData::LocalDir, QStringList(QStringLiteral("kshorturifilter")), QStringLiteral("/tmp"));
0249     addRow("~bin", nullptr, KUriFilterData::LocalDir, QStringList(QStringLiteral("kshorturifilter")));
0250     addRow("~does_not_exist", nullptr, KUriFilterData::Error, QStringList(QStringLiteral("kshorturifilter")));
0251     addRow("~/does_not_exist", QDir::homePath() + "/does_not_exist", KUriFilterData::LocalFile, QStringList(QStringLiteral("kshorturifilter")));
0252 
0253     // Absolute Path tests for kshorturifilter
0254     const QStringList kshorturifilter(QStringLiteral("kshorturifilter"));
0255     addRow("./", datahome, KUriFilterData::LocalDir, kshorturifilter, datahome + QStringLiteral("/")); // cleanPath removes the trailing slash
0256     const QString parentDir = QDir().cleanPath(datahome + QStringLiteral("/.."));
0257     addRow("../", QFile::encodeName(parentDir), KUriFilterData::LocalDir, kshorturifilter, datahome);
0258     addRow("share", datahome, KUriFilterData::LocalDir, kshorturifilter, QFile::encodeName(parentDir));
0259     // Invalid URLs
0260     addRow("http://a[b]", QStringLiteral("http://a[b]"), KUriFilterData::Unknown, kshorturifilter, QStringLiteral("/"));
0261 }
0262 
0263 void KUriFilterTest::localFiles()
0264 {
0265     runFilterTest();
0266 }
0267 
0268 void KUriFilterTest::refOrQuery_data()
0269 {
0270     setupColumns();
0271     // URL with reference
0272     addRow("http://www.kde.org/index.html#q8", QStringLiteral("http://www.kde.org/index.html#q8"), KUriFilterData::NetProtocol);
0273     // local file with reference
0274     addRow("file:/etc/passwd#q8", QStringLiteral("file:///etc/passwd#q8"), KUriFilterData::LocalFile);
0275     addRow("file:///etc/passwd#q8", QStringLiteral("file:///etc/passwd#q8"), KUriFilterData::LocalFile);
0276     addRow("/etc/passwd#q8", QStringLiteral("file:///etc/passwd#q8"), KUriFilterData::LocalFile);
0277     // local file with query (can be used by javascript)
0278     addRow("file:/etc/passwd?foo=bar", QStringLiteral("file:///etc/passwd?foo=bar"), KUriFilterData::LocalFile);
0279     testLocalFile(QStringLiteral("/tmp/kurifiltertest?foo")); // local file with ? in the name (#58990)
0280     testLocalFile(QStringLiteral("/tmp/kurlfiltertest#foo")); // local file with '#' in the name
0281     testLocalFile(QStringLiteral("/tmp/kurlfiltertest#foo?bar")); // local file with both
0282     testLocalFile(QStringLiteral("/tmp/kurlfiltertest?foo#bar")); // local file with both, the other way round
0283 }
0284 
0285 void KUriFilterTest::refOrQuery()
0286 {
0287     runFilterTest();
0288 }
0289 
0290 void KUriFilterTest::shortUris_data()
0291 {
0292     setupColumns();
0293     // hostnames are lowercased by QUrl
0294     // qtbase commit eaf4438b3511c preserves the double slashes
0295     addRow("http://www.myDomain.commyPort/ViewObjectRes//Default:name=hello",
0296            QStringLiteral("http://www.mydomain.commyport/ViewObjectRes//Default:name=hello"),
0297            KUriFilterData::NetProtocol);
0298     addRow("http://www.myDomain.commyPort/ViewObjectRes/Default:name=hello?a=a///////",
0299            QStringLiteral("http://www.mydomain.commyport/ViewObjectRes/Default:name=hello?a=a///////"),
0300            KUriFilterData::NetProtocol);
0301     addRow("ftp://ftp.kde.org", QStringLiteral("ftp://ftp.kde.org"), KUriFilterData::NetProtocol);
0302     addRow("ftp://username@ftp.kde.org:500", QStringLiteral("ftp://username@ftp.kde.org:500"), KUriFilterData::NetProtocol);
0303 
0304     // ShortURI/LocalDomain filter tests.
0305     addRow("linuxtoday.com", QStringLiteral("https://linuxtoday.com"), KUriFilterData::NetProtocol);
0306     addRow("LINUXTODAY.COM", QStringLiteral("https://linuxtoday.com"), KUriFilterData::NetProtocol);
0307     addRow("kde.org", QStringLiteral("https://kde.org"), KUriFilterData::NetProtocol);
0308     addRow("ftp.kde.org", QStringLiteral("ftp://ftp.kde.org"), KUriFilterData::NetProtocol);
0309     addRow("ftp.kde.org:21", QStringLiteral("ftp://ftp.kde.org:21"), KUriFilterData::NetProtocol);
0310     addRow("cr.yp.to", QStringLiteral("https://cr.yp.to"), KUriFilterData::NetProtocol);
0311     addRow("www.kde.org:21", QStringLiteral("https://www.kde.org:21"), KUriFilterData::NetProtocol);
0312     // This one passes but the DNS lookup takes 5 seconds to fail
0313     // addRow("foobar.local:8000", QStringLiteral("https://foobar.local:8000"), KUriFilterData::NetProtocol);
0314     addRow("foo@bar.com", QStringLiteral("mailto:foo@bar.com"), KUriFilterData::NetProtocol);
0315     addRow("firstname.lastname@x.foo.bar", QStringLiteral("mailto:firstname.lastname@x.foo.bar"), KUriFilterData::NetProtocol);
0316     addRow("mailto:foo@bar.com", QStringLiteral("mailto:foo@bar.com"), KUriFilterData::NetProtocol);
0317     addRow("www.123.foo", QStringLiteral("https://www.123.foo"), KUriFilterData::NetProtocol);
0318     addRow("user@www.123.foo:3128", QStringLiteral("https://user@www.123.foo:3128"), KUriFilterData::NetProtocol);
0319     addRow("ftp://user@user@www.123.foo:3128", QStringLiteral("ftp://user%40user@www.123.foo:3128"), KUriFilterData::NetProtocol);
0320     addRow("user@user@www.123.foo:3128", QStringLiteral("https://user%40user@www.123.foo:3128"), KUriFilterData::NetProtocol);
0321 
0322     // IPv4 address formats...
0323     addRow("user@192.168.1.0:3128", QStringLiteral("https://user@192.168.1.0:3128"), KUriFilterData::NetProtocol);
0324     addRow("127.0.0.1", QStringLiteral("https://127.0.0.1"), KUriFilterData::NetProtocol);
0325     addRow("127.0.0.1:3128", QStringLiteral("https://127.0.0.1:3128"), KUriFilterData::NetProtocol);
0326     addRow("127.1", QStringLiteral("https://127.0.0.1"), KUriFilterData::NetProtocol); // Qt5: QUrl resolves to 127.0.0.1
0327     addRow("127.0.1", QStringLiteral("https://127.0.0.1"), KUriFilterData::NetProtocol); // Qt5: QUrl resolves to 127.0.0.1
0328 
0329     // IPv6 address formats (taken from RFC 2732)...
0330     addRow("[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html",
0331            QStringLiteral("https://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:80/index.html"),
0332            KUriFilterData::NetProtocol);
0333     addRow("[1080:0:0:0:8:800:200C:417A]/index.html",
0334            QStringLiteral("https://[1080::8:800:200c:417a]/index.html"),
0335            KUriFilterData::NetProtocol); // Qt5 QUrl change
0336     addRow("[3ffe:2a00:100:7031::1]", QStringLiteral("https://[3ffe:2a00:100:7031::1]"), KUriFilterData::NetProtocol);
0337     addRow("[1080::8:800:200C:417A]/foo", QStringLiteral("https://[1080::8:800:200c:417a]/foo"), KUriFilterData::NetProtocol);
0338     addRow("[::192.9.5.5]/ipng", QStringLiteral("https://[::192.9.5.5]/ipng"), KUriFilterData::NetProtocol);
0339     addRow("[::FFFF:129.144.52.38]:80/index.html", QStringLiteral("https://[::ffff:129.144.52.38]:80/index.html"), KUriFilterData::NetProtocol);
0340     addRow("[2010:836B:4179::836B:4179]", QStringLiteral("https://[2010:836b:4179::836b:4179]"), KUriFilterData::NetProtocol);
0341 
0342     // Local domain filter - If you uncomment these test, make sure you
0343     // you adjust it based on the localhost entry in your /etc/hosts file.
0344     // addRow( "localhost:3128", "http://localhost.localdomain:3128", KUriFilterData::NetProtocol );
0345     // addRow( "localhost", "http://localhost.localdomain", KUriFilterData::NetProtocol );
0346     // addRow( "localhost/~blah", "http://localhost.localdomain/~blah", KUriFilterData::NetProtocol );
0347 
0348     addRow("user@host.domain", QStringLiteral("mailto:user@host.domain"), KUriFilterData::NetProtocol); // new in KDE-3.2
0349 
0350     // Windows style SMB (UNC) URL. Should be converted into the valid smb format...
0351     addRow("\\\\mainserver\\share\\file", QStringLiteral("smb://mainserver/share/file"), KUriFilterData::NetProtocol);
0352 
0353     // KDE3: was not be filtered at all. All valid protocols of this form were be ignored.
0354     // KDE4: parsed as "network protocol", seems fine to me (DF)
0355     addRow("ftp:", QStringLiteral("ftp:"), KUriFilterData::NetProtocol);
0356     addRow("http:", QStringLiteral("http:"), KUriFilterData::NetProtocol);
0357 
0358     // The default search engine is set to 'Google'
0359     addRow("gg:", QLatin1String(""), KUriFilterData::NetProtocol); // see bug 56218
0360     // disable localdomain in case the local DNS or /etc/hosts knows domains KDE or HTTP (e.g. due to search domain)
0361     addRow("KDE",
0362            QStringLiteral("https://www.google.com/search?q=KDE&ie=UTF-8"),
0363            KUriFilterData::NetProtocol,
0364            {QStringLiteral("kshorturifilter"), QStringLiteral("kuriikwsfilter")});
0365     addRow("HTTP",
0366            QStringLiteral("https://www.google.com/search?q=HTTP&ie=UTF-8"),
0367            KUriFilterData::NetProtocol,
0368            {QStringLiteral("kshorturifilter"), QStringLiteral("kuriikwsfilter")});
0369 }
0370 
0371 void KUriFilterTest::shortUris()
0372 {
0373     runFilterTest();
0374 }
0375 
0376 void KUriFilterTest::executables_data()
0377 {
0378     setupColumns();
0379     // Executable tests - No IKWS in minicli
0380     addRow("cp", QStringLiteral("cp"), KUriFilterData::Executable, minicliFilters);
0381     addRow("kbuildsycoca5", QStringLiteral("kbuildsycoca5"), KUriFilterData::Executable, minicliFilters);
0382     addRow("KDE", QStringLiteral("KDE"), s_noFiltering, minicliFilters);
0383     addRow("does/not/exist", QStringLiteral("does/not/exist"), s_noFiltering, minicliFilters);
0384     addRow("/does/not/exist", QStringLiteral("/does/not/exist"), KUriFilterData::LocalFile, minicliFilters);
0385     addRow("/does/not/exist#a", QStringLiteral("/does/not/exist#a"), KUriFilterData::LocalFile, minicliFilters);
0386     addRow("kbuildsycoca5 --help", QStringLiteral("kbuildsycoca5 --help"), KUriFilterData::Executable, minicliFilters); // the args are in argsAndOptions()
0387     addRow("/bin/sh", QStringLiteral("/bin/sh"), KUriFilterData::Executable, minicliFilters);
0388     addRow("/bin/sh -q -option arg1",
0389            QStringLiteral("/bin/sh -q -option arg1"),
0390            KUriFilterData::Executable,
0391            minicliFilters); // the args are in argsAndOptions()
0392 
0393     // Typing 'cp' or any other valid unix command in konq's location bar should result in
0394     // a search using the default search engine
0395     // 'ls' is a bit of a special case though, due to the toplevel domain called 'ls'
0396     addRow("cp",
0397            QStringLiteral("https://www.google.com/search?q=cp&ie=UTF-8"),
0398            KUriFilterData::NetProtocol,
0399            QStringList(),
0400            nullptr,
0401            false /* don't check for executables, see konq_misc.cc */);
0402 }
0403 
0404 void KUriFilterTest::executables()
0405 {
0406     runFilterTest();
0407 }
0408 
0409 void KUriFilterTest::environmentVariables_data()
0410 {
0411     setupColumns();
0412     // ENVIRONMENT variable
0413     qputenv("SOMEVAR", "/somevar");
0414     qputenv("ETC", "/etc");
0415 
0416     addRow("$SOMEVAR/kdelibs/kio", "/somevar/kdelibs/kio", KUriFilterData::LocalFile); // note: this dir doesn't exist...
0417     addRow("$ETC/passwd", QStringLiteral("/etc/passwd"), KUriFilterData::LocalFile);
0418     QString qtdocPath = qtdir + QStringLiteral("/doc/html/functions.html");
0419     if (QFile::exists(qtdocPath)) {
0420         QString expectedUrl = QUrl::fromLocalFile(qtdocPath).toString() + "#s";
0421         addRow("$QTDIR/doc/html/functions.html#s", expectedUrl.toUtf8(), KUriFilterData::LocalFile);
0422     }
0423     addRow("http://www.kde.org/$USER", QStringLiteral("http://www.kde.org/$USER"), KUriFilterData::NetProtocol); // no expansion
0424 
0425     addRow("$DATAHOME", datahome, KUriFilterData::LocalDir);
0426     QDir().mkpath(datahome + QStringLiteral("/urifilter/a+plus"));
0427     addRow("$DATAHOME/urifilter/a+plus", datahome + QStringLiteral("/urifilter/a+plus"), KUriFilterData::LocalDir);
0428 
0429     // BR 27788
0430     QDir().mkpath(datahome + QStringLiteral("/Dir With Space"));
0431     addRow("$DATAHOME/Dir With Space", datahome + QStringLiteral("/Dir With Space"), KUriFilterData::LocalDir);
0432 
0433     // support for name filters (BR 93825)
0434     addRow("$DATAHOME/*.txt", datahome + QStringLiteral("/*.txt"), KUriFilterData::LocalDir);
0435     addRow("$DATAHOME/[a-b]*.txt", datahome + QStringLiteral("/[a-b]*.txt"), KUriFilterData::LocalDir);
0436     addRow("$DATAHOME/a?c.txt", datahome + QStringLiteral("/a?c.txt"), KUriFilterData::LocalDir);
0437     addRow("$DATAHOME/?c.txt", datahome + QStringLiteral("/?c.txt"), KUriFilterData::LocalDir);
0438     // but let's check that a directory with * in the name still works
0439     QDir().mkpath(datahome + QStringLiteral("/share/Dir*With*Stars"));
0440     addRow("$DATAHOME/Dir*With*Stars", datahome + QStringLiteral("/Dir*With*Stars"), KUriFilterData::LocalDir);
0441     QDir().mkpath(datahome + QStringLiteral("/Dir?QuestionMark"));
0442     addRow("$DATAHOME/Dir?QuestionMark", datahome + QStringLiteral("/Dir?QuestionMark"), KUriFilterData::LocalDir);
0443     QDir().mkpath(datahome + QStringLiteral("/Dir[Bracket"));
0444     addRow("$DATAHOME/Dir[Bracket", datahome + QStringLiteral("/Dir[Bracket"), KUriFilterData::LocalDir);
0445 
0446     addRow("$HOME/$KDEDIR/kdebase/kcontrol/ebrowsing", "", KUriFilterData::LocalFile);
0447     addRow("$1/$2/$3",
0448            QStringLiteral("https://www.google.com/search?q=%241%2F%242%2F%243&ie=UTF-8"),
0449            KUriFilterData::NetProtocol); // can be used as bogus or valid test. Currently triggers default search, i.e. google
0450     addRow("$$$$", QStringLiteral("https://www.google.com/search?q=%24%24%24%24&ie=UTF-8"), KUriFilterData::NetProtocol); // worst case scenarios.
0451 
0452     if (!qtdir.isEmpty()) {
0453         addRow("$QTDIR", qtdir, KUriFilterData::LocalDir, QStringList(QStringLiteral("kshorturifilter"))); // use specific filter.
0454     }
0455     addRow("$HOME", home, KUriFilterData::LocalDir, QStringList(QStringLiteral("kshorturifilter"))); // use specific filter.
0456 }
0457 
0458 void KUriFilterTest::environmentVariables()
0459 {
0460     runFilterTest();
0461 }
0462 
0463 void KUriFilterTest::internetKeywords_data()
0464 {
0465     setupColumns();
0466     addRow(QString::asprintf("gg%cfoo bar", s_delimiter).toUtf8(),
0467            QStringLiteral("https://www.google.com/search?q=foo%20bar&ie=UTF-8"),
0468            KUriFilterData::NetProtocol);
0469     addRow("!gg foo bar", QStringLiteral("https://www.google.com/search?q=foo%20bar&ie=UTF-8"), KUriFilterData::NetProtocol);
0470     addRow("foo !gg bar", QStringLiteral("https://www.google.com/search?q=foo%20bar&ie=UTF-8"), KUriFilterData::NetProtocol);
0471     addRow("foo bar!gg", QStringLiteral("https://www.google.com/search?q=foo%20bar&ie=UTF-8"), KUriFilterData::NetProtocol);
0472     addRow("wp bar!gg", QStringLiteral("https://www.google.com/search?q=wp%20bar&ie=UTF-8"), KUriFilterData::NetProtocol);
0473     addRow(QString::asprintf("bug%c55798", s_delimiter).toUtf8(),
0474            QStringLiteral("https://bugs.kde.org/buglist.cgi?quicksearch=55798"),
0475            KUriFilterData::NetProtocol);
0476 
0477     // See https://bugs.kde.org/show_bug.cgi?id=437660
0478     addRow(QString::asprintf("bug%c55798!does_not_exist", s_delimiter).toUtf8(),
0479            QStringLiteral("https://bugs.kde.org/buglist.cgi?quicksearch=55798%21does_not_exist"),
0480            KUriFilterData::NetProtocol);
0481 
0482     addRow(QString::asprintf("gg%cC++", s_delimiter).toUtf8(), QStringLiteral("https://www.google.com/search?q=C%2B%2B&ie=UTF-8"), KUriFilterData::NetProtocol);
0483     addRow(QString::asprintf("gg%cC#", s_delimiter).toUtf8(), QStringLiteral("https://www.google.com/search?q=C%23&ie=UTF-8"), KUriFilterData::NetProtocol);
0484     addRow(QString::asprintf("ya%cfoo bar was here", s_delimiter).toUtf8(), nullptr, -1); // this triggers default search, i.e. google
0485     addRow(QString::asprintf("gg%cwww.kde.org", s_delimiter).toUtf8(),
0486            QStringLiteral("https://www.google.com/search?q=www.kde.org&ie=UTF-8"),
0487            KUriFilterData::NetProtocol);
0488     addRow(QStringLiteral("gg%1é").arg(s_delimiter).toUtf8() /*eaccent in utf8*/,
0489            QStringLiteral("https://www.google.com/search?q=%C3%A9&ie=UTF-8"),
0490            KUriFilterData::NetProtocol);
0491     addRow(QStringLiteral("gg%1прйвет").arg(s_delimiter).toUtf8() /* greetings in russian utf-8*/,
0492            QStringLiteral("https://www.google.com/search?q=%D0%BF%D1%80%D0%B9%D0%B2%D0%B5%D1%82&ie=UTF-8"),
0493            KUriFilterData::NetProtocol);
0494 }
0495 
0496 void KUriFilterTest::internetKeywords()
0497 {
0498     runFilterTest();
0499 }
0500 
0501 void KUriFilterTest::localdomain()
0502 {
0503     const QString host = QHostInfo::localHostName();
0504     if (host.isEmpty()) {
0505         const QString expected = QLatin1String("http://") + host;
0506         runFilterTest(host, expected, KUriFilterData::NetProtocol, QStringList{QStringLiteral("localdomainurifilter")}, nullptr, false);
0507     }
0508 }
0509 
0510 void KUriFilterTest::relativeGoUp()
0511 {
0512     // When the text is "../"
0513     KUriFilterData filteredData(QStringLiteral("../"));
0514     filteredData.setCheckForExecutables(false);
0515     // Using kshorturifilter
0516     const auto filtersList = QStringList{QStringLiteral("kshorturifilter")};
0517     // Then the text isn't filtered and returned as-is
0518     QVERIFY(!KUriFilter::self()->filterUri(filteredData, filtersList));
0519 }
0520 
0521 #include "moc_kurifiltertest.cpp"