[education/rkward/kf5] rkward/misc: Work around changes in QDomDocument parsing of undeclared entities
Thomas Friedrichsmeier
null at kde.org
Wed Apr 10 16:12:08 BST 2024
Git commit 4ea710a77a90f1329ab57661283495bffdffe42c by Thomas Friedrichsmeier.
Committed on 01/04/2024 at 13:47.
Pushed by tfry into branch 'kf5'.
Work around changes in QDomDocument parsing of undeclared entities
M +22 -2 rkward/misc/xmlhelper.cpp
https://invent.kde.org/education/rkward/-/commit/4ea710a77a90f1329ab57661283495bffdffe42c
diff --git a/rkward/misc/xmlhelper.cpp b/rkward/misc/xmlhelper.cpp
index 73dca384e..0a884dcf1 100644
--- a/rkward/misc/xmlhelper.cpp
+++ b/rkward/misc/xmlhelper.cpp
@@ -1,6 +1,6 @@
/*
xmlhelper.cpp - This file is part of RKWard (https://rkward.kde.org). Created: Fri May 6 2005
-SPDX-FileCopyrightText: 2005-2014 by Thomas Friedrichsmeier <thomas.friedrichsmeier at kdemail.net>
+SPDX-FileCopyrightText: 2005-2024 by Thomas Friedrichsmeier <thomas.friedrichsmeier at kdemail.net>
SPDX-FileContributor: The RKWard Team <rkward-devel at kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
@@ -14,11 +14,24 @@ SPDX-License-Identifier: GPL-2.0-or-later
#include <qfileinfo.h>
#include <qdir.h>
#include <QTextStream>
+#include <QXmlStreamReader>
+#include <QXmlStreamEntityResolver>
#include <rkmessagecatalog.h>
#include "../debug.h"
+/* We want to allow undelcared entities in our XML files, importantly arbitrary HTML entities inside our .rkh files. Further, we want to
+ * preserve them *non-replaced* in order to pass them along to the webegine for rendering.
+ *
+ * Arguably, this approach has always been hackist, but it used to work without the following acrobatics, for many years:
+ * When an unresolved entity is encountered, replace it by a pseudo-element that will be converted back to a regular entity in
+ * i18nElementText(). */
+#define ENTITIYHACK "RKENTITY"
+class DummyEntityResolver : public QXmlStreamEntityResolver {
+ QString resolveUndeclaredEntity(const QString &name) override { return QString("<" ENTITIYHACK ">%1</" ENTITIYHACK ">").arg(name); }
+};
+
XMLHelper::XMLHelper (const QString &filename, const RKMessageCatalog *default_catalog) {
RK_TRACE (XML);
XMLHelper::filename = filename;
@@ -39,7 +52,10 @@ QDomElement XMLHelper::openXMLFile (int debug_level, bool with_includes, bool wi
QFile f (filename);
if (!f.open(QIODevice::ReadOnly)) displayError(nullptr, i18n("Could not open file %1 for reading", filename), debug_level, DL_ERROR);
- if (!doc.setContent(&f, false, &error_message, &error_line, &error_column)) {
+ QXmlStreamReader reader(&f);
+ DummyEntityResolver res;
+ reader.setEntityResolver(&res);
+ if (!doc.setContent(&reader, false, &error_message, &error_line, &error_column)) {
displayError(nullptr, i18n("Error parsing XML-file. Error-message was: '%1' in line '%2', column '%3'. Expect further errors to be reported below", error_message, error_line, error_column), debug_level, DL_ERROR);
return QDomElement ();
}
@@ -239,6 +255,7 @@ QString XMLHelper::i18nStringAttribute (const QDomElement& element, const QStrin
}
QString attr = element.attribute (name);
+ if(attr.contains("Analysis")) displayError(&element, attr, DL_ERROR);
if (attr.isEmpty ()) return attr; // Do not translate empty strings!
const QString context = element.attribute ("i18n_context", QString ());
@@ -363,6 +380,9 @@ QString XMLHelper::i18nElementText (const QDomElement &element, bool with_paragr
ret.append (buffer);
buffer.clear ();
continue;
+ } else if (e.tagName() == QLatin1String(ENTITIYHACK)) {
+ ret.append(QChar('&') + e.text() + QChar(';'));
+ continue;
}
}
node.save (stream, 0);
More information about the rkward-tracker
mailing list