From: Claudio Cambra Date: Thu, 20 Apr 2023 07:35:46 +0000 (+0800) Subject: Simplify Propfind XML parsing using QDomDocument instead of complex QXmlStreamReader... X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~10^2~49^2~17 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=43bcecdeb05f716588d0e04e357a571619e11c08;p=nextcloud-desktop.git Simplify Propfind XML parsing using QDomDocument instead of complex QXmlStreamReader-based parsing Signed-off-by: Claudio Cambra --- diff --git a/src/libsync/CMakeLists.txt b/src/libsync/CMakeLists.txt index a6ccb6d4f..ecf6a9125 100644 --- a/src/libsync/CMakeLists.txt +++ b/src/libsync/CMakeLists.txt @@ -171,7 +171,7 @@ IF (NOT APPLE) ) ENDIF(NOT APPLE) -find_package(Qt5 REQUIRED COMPONENTS WebSockets) +find_package(Qt5 REQUIRED COMPONENTS WebSockets Xml) add_library(nextcloudsync SHARED ${libsync_SRCS}) add_library(Nextcloud::sync ALIAS nextcloudsync) @@ -185,6 +185,7 @@ target_link_libraries(nextcloudsync Qt5::Core Qt5::Network Qt5::WebSockets + Qt5::Xml ) if (NOT TOKEN_AUTH_ONLY) diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp index 152e95fa7..b40f6653e 100644 --- a/src/libsync/networkjobs.cpp +++ b/src/libsync/networkjobs.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -608,34 +609,43 @@ bool PropfindJob::finished() if (http_result_code == 207) { // Parse DAV response - QXmlStreamReader reader(reply()); - reader.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("d", "DAV:")); + auto items = QVariantMap(); + auto domDocument = QDomDocument(); + auto errorMsg = QString(); + auto errorLine = -1; + auto errorColumn = -1; + + if (!domDocument.setContent(reply(), true, &errorMsg, &errorLine, &errorColumn)) { + qCWarning(lcPropfindJob) << "XML parser error: " << errorMsg << errorLine << errorColumn; + emit finishedWithError(reply()); + return true; + } - QVariantMap items; - // introduced to nesting is ignored - QStack curElement; + const auto rootElement = domDocument.documentElement(); + const auto propNodes = rootElement.elementsByTagName("prop"); - while (!reader.atEnd()) { - const auto type = reader.readNext(); - if (type == QXmlStreamReader::StartElement) { - if (!curElement.isEmpty() && curElement.top() == QLatin1String("prop")) { - items.insert(reader.name().toString(), reader.readElementText(QXmlStreamReader::SkipChildElements)); - } else { - curElement.push(reader.name().toString()); - } + for (auto i = 0; i < propNodes.count(); ++i) { + const auto propNode = propNodes.at(i); + const auto propElement = propNode.toElement(); + + if (propElement.isNull() || propElement.tagName() != "prop") { + continue; } - if (type == QXmlStreamReader::EndElement) { - if (curElement.top() == reader.name()) { - curElement.pop(); + + auto propChildNode = propElement.firstChild(); + + while (!propChildNode.isNull()) { + const auto propChildElement = propChildNode.toElement(); + + if (!propChildElement.isNull()) { + items.insert(propChildElement.tagName(), propChildElement.text()); } + + propChildNode = propChildNode.nextSibling(); } - } - if (reader.hasError()) { - qCWarning(lcPropfindJob) << "XML parser error: " << reader.errorString(); - emit finishedWithError(reply()); - } else { - emit result(items); - } + } + + emit result(items); } else { qCWarning(lcPropfindJob) << "*not* successful, http result code is" << http_result_code << (http_result_code == 302 ? reply()->header(QNetworkRequest::LocationHeader).toString() : QLatin1String(""));