[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