From: Markus Goetz Date: Thu, 7 May 2015 15:19:14 +0000 (+0200) Subject: Discovery: Test better, treat invalid hrefs as error #3176 X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~1803^2~115 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0359c775e03906b07af9d18d7fae5d814fc88e5f;p=nextcloud-desktop.git Discovery: Test better, treat invalid hrefs as error #3176 --- diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp index 7e92d96c1..8a43e5cea 100644 --- a/src/libsync/networkjobs.cpp +++ b/src/libsync/networkjobs.cpp @@ -350,7 +350,7 @@ LsColXMLParser::LsColXMLParser() } -bool LsColXMLParser::parse( const QByteArray& xml, QHash *sizes) +bool LsColXMLParser::parse( const QByteArray& xml, QHash *sizes, const QString& expectedPath) { // Parse DAV response QXmlStreamReader reader(xml); @@ -371,7 +371,14 @@ bool LsColXMLParser::parse( const QByteArray& xml, QHash *sizes // Start elements with DAV: if (type == QXmlStreamReader::StartElement && reader.namespaceUri() == QLatin1String("DAV:")) { if (name == QLatin1String("href")) { - currentHref = QUrl::fromPercentEncoding(reader.readElementText().toUtf8()); + // We don't use URL encoding in our request URL (which is the expected path) (QNAM will do it for us) + // but the result will have URL encoding.. + QString hrefString = QString::fromUtf8(QByteArray::fromPercentEncoding(reader.readElementText().toUtf8())); + if (!hrefString.startsWith(expectedPath)) { + qDebug() << "Invalid href" << hrefString << "expected starting with" << expectedPath; + return false; + } + currentHref = hrefString; } else if (name == QLatin1String("response")) { } else if (name == QLatin1String("propstat")) { insidePropstat = true; @@ -520,7 +527,8 @@ bool LsColJob::finished() connect( &parser, SIGNAL(finishedWithoutError()), this, SIGNAL(finishedWithoutError()) ); - if( !parser.parse( reply()->readAll(), &_sizes ) ) { + QString expectedPath = reply()->request().url().path(); // something like "/owncloud/remote.php/webdav/folder" + if( !parser.parse( reply()->readAll(), &_sizes, expectedPath ) ) { // XML parse error emit finishedWithError(reply()); } diff --git a/src/libsync/networkjobs.h b/src/libsync/networkjobs.h index f3bc5d1bf..868207da7 100644 --- a/src/libsync/networkjobs.h +++ b/src/libsync/networkjobs.h @@ -137,7 +137,7 @@ class OWNCLOUDSYNC_EXPORT LsColXMLParser : public QObject { public: explicit LsColXMLParser(); - bool parse(const QByteArray &xml, QHash *sizes); + bool parse(const QByteArray &xml, QHash *sizes, const QString& expectedPath); signals: void directoryListingSubfolders(const QStringList &items); diff --git a/test/testxmlparse.h b/test/testxmlparse.h index add06cdd8..0b667eb50 100644 --- a/test/testxmlparse.h +++ b/test/testxmlparse.h @@ -113,7 +113,7 @@ private slots: this, SLOT(slotFinishedSuccessfully()) ); QHash sizes; - QVERIFY(parser.parse( testXml, &sizes )); + QVERIFY(parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" )); QVERIFY(_success); QVERIFY(sizes.size() == 0 ); // No quota info in the XML @@ -187,7 +187,7 @@ private slots: this, SLOT(slotFinishedSuccessfully()) ); QHash sizes; - QVERIFY(false == parser.parse( testXml, &sizes )); // verify false + QVERIFY(false == parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" )); // verify false QVERIFY(!_success); QVERIFY(sizes.size() == 0 ); // No quota info in the XML @@ -210,7 +210,7 @@ private slots: this, SLOT(slotFinishedSuccessfully()) ); QHash sizes; - QVERIFY(false == parser.parse( testXml, &sizes )); // verify false + QVERIFY(false == parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" )); // verify false QVERIFY(!_success); QVERIFY(sizes.size() == 0 ); // No quota info in the XML @@ -232,7 +232,7 @@ private slots: this, SLOT(slotFinishedSuccessfully()) ); QHash sizes; - QVERIFY(false == parser.parse( testXml, &sizes )); // verify false + QVERIFY(false == parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" )); // verify false QVERIFY(!_success); QVERIFY(sizes.size() == 0 ); // No quota info in the XML @@ -240,6 +240,208 @@ private slots: QVERIFY(_items.size() == 0 ); // FIXME: We should change the parser to not emit during parsing but at the end QVERIFY(_subdirs.size() == 0); } + + void testParserBogfusHref1() { + const QByteArray testXml = "" + "" + "" + "http://127.0.0.1:81/oc/remote.php/webdav/sharefolder/" + "" + "" + "00004213ocobzus5kn6s" + "RDNVCK" + "121780" + "\"5527beb0400b0\"" + "" + "" + "" + "Fri, 06 Feb 2015 13:49:55 GMT" + "" + "HTTP/1.1 200 OK" + "" + "" + "" + "" + "" + "" + "" + "HTTP/1.1 404 Not Found" + "" + "" + "" + "http://127.0.0.1:81/oc/remote.php/webdav/sharefolder/quitte.pdf" + "" + "" + "00004215ocobzus5kn6s" + "RDNVW" + "\"2fa2f0d9ed49ea0c3e409d49e652dea0\"" + "" + "Fri, 06 Feb 2015 13:49:55 GMT" + "121780" + "" + "HTTP/1.1 200 OK" + "" + "" + "" + "" + "" + "" + "HTTP/1.1 404 Not Found" + "" + "" + ""; + + + LsColXMLParser parser; + + connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)), + this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) ); + connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap&)), + this, SLOT(slotDirectoryListingIterated(const QString&, const QMap&)) ); + connect( &parser, SIGNAL(finishedWithoutError()), + this, SLOT(slotFinishedSuccessfully()) ); + + QHash sizes; + QVERIFY(false == parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" )); + QVERIFY(!_success); + } + + void testParserBogfusHref2() { + const QByteArray testXml = "" + "" + "" + "/sharefolder" + "" + "" + "00004213ocobzus5kn6s" + "RDNVCK" + "121780" + "\"5527beb0400b0\"" + "" + "" + "" + "Fri, 06 Feb 2015 13:49:55 GMT" + "" + "HTTP/1.1 200 OK" + "" + "" + "" + "" + "" + "" + "" + "HTTP/1.1 404 Not Found" + "" + "" + "" + "/sharefolder/quitte.pdf" + "" + "" + "00004215ocobzus5kn6s" + "RDNVW" + "\"2fa2f0d9ed49ea0c3e409d49e652dea0\"" + "" + "Fri, 06 Feb 2015 13:49:55 GMT" + "121780" + "" + "HTTP/1.1 200 OK" + "" + "" + "" + "" + "" + "" + "HTTP/1.1 404 Not Found" + "" + "" + ""; + + + LsColXMLParser parser; + + connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)), + this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) ); + connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap&)), + this, SLOT(slotDirectoryListingIterated(const QString&, const QMap&)) ); + connect( &parser, SIGNAL(finishedWithoutError()), + this, SLOT(slotFinishedSuccessfully()) ); + + QHash sizes; + QVERIFY(false == parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" )); + QVERIFY(!_success); + } + + void testHrefUrlEncoding() { + const QByteArray testXml = "" + "" + "" + "/%C3%A4" // a-umlaut utf8 + "" + "" + "00004213ocobzus5kn6s" + "RDNVCK" + "121780" + "\"5527beb0400b0\"" + "" + "" + "" + "Fri, 06 Feb 2015 13:49:55 GMT" + "" + "HTTP/1.1 200 OK" + "" + "" + "" + "" + "" + "" + "" + "HTTP/1.1 404 Not Found" + "" + "" + "" + "/%C3%A4/%C3%A4.pdf" + "" + "" + "00004215ocobzus5kn6s" + "RDNVW" + "\"2fa2f0d9ed49ea0c3e409d49e652dea0\"" + "" + "Fri, 06 Feb 2015 13:49:55 GMT" + "121780" + "" + "HTTP/1.1 200 OK" + "" + "" + "" + "" + "" + "" + "HTTP/1.1 404 Not Found" + "" + "" + ""; + + LsColXMLParser parser; + + connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)), + this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) ); + connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap&)), + this, SLOT(slotDirectoryListingIterated(const QString&, const QMap&)) ); + connect( &parser, SIGNAL(finishedWithoutError()), + this, SLOT(slotFinishedSuccessfully()) ); + + QHash sizes; + QVERIFY(parser.parse( testXml, &sizes, "/ä" )); + QVERIFY(_success); + + QVERIFY(_items.contains("/ä/ä.pdf")); + QVERIFY(_items.contains("/ä")); + QVERIFY(_items.size() == 2 ); + + QVERIFY(_subdirs.contains("/ä")); + QVERIFY(_subdirs.size() == 1); + } + }; #endif