diff options
author | Ulf Hermann <[email protected]> | 2025-04-10 17:11:42 +0200 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2025-04-11 15:50:24 +0200 |
commit | 916f5b51c8ec3595e054e4bf8e62949258a552ee (patch) | |
tree | 46ca2654d47ad1314318f414b42786cbcaf4d42c | |
parent | f181086eeb370f7ba7fabc8434c77b2768a0afee (diff) |
qmltc: Properly escape translation strings
We have QQmlJSUtils::toLiteral() for that. Extend it to handle byte
arrays in addition to strings and use it.
Fixes: QTBUG-134726
Change-Id: Ibde1f56b25794fc8c49b796303c4f39933aedb42
Reviewed-by: Olivier De Cannière <[email protected]>
-rw-r--r-- | src/qmlcompiler/qqmljsutils_p.h | 21 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/QmltcTests/newLineTranslation.qml | 6 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/tst_qmltc.cpp | 9 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/tst_qmltc.h | 2 | ||||
-rw-r--r-- | tools/qmltc/qmltccompilerpieces.cpp | 32 |
6 files changed, 49 insertions, 23 deletions
diff --git a/src/qmlcompiler/qqmljsutils_p.h b/src/qmlcompiler/qqmljsutils_p.h index 56aec3dd78..1b4a5b707d 100644 --- a/src/qmlcompiler/qqmljsutils_p.h +++ b/src/qmlcompiler/qqmljsutils_p.h @@ -73,13 +73,13 @@ struct Q_QMLCOMPILER_EXPORT QQmlJSUtils Returns escaped version of \a s. This function is mostly useful for code generators. */ - static QString escapeString(QString s) + template<typename String, typename CharacterLiteral, typename StringView> + static String escapeString(String s) { - using namespace Qt::StringLiterals; - return s.replace('\\'_L1, "\\\\"_L1) - .replace('"'_L1, "\\\""_L1) - .replace('\n'_L1, "\\n"_L1) - .replace('?'_L1, "\\?"_L1); + return s.replace(CharacterLiteral('\\'), StringView("\\\\")) + .replace(CharacterLiteral('"'), StringView("\\\"")) + .replace(CharacterLiteral('\n'), StringView("\\n")) + .replace(CharacterLiteral('?'), StringView("\\?")); } /*! \internal @@ -89,9 +89,14 @@ struct Q_QMLCOMPILER_EXPORT QQmlJSUtils \note This function escapes \a s before wrapping it. */ - static QString toLiteral(const QString &s, QStringView ctor = u"QStringLiteral") + template< + typename String = QString, + typename CharacterLiteral = QLatin1Char, + typename StringView = QLatin1StringView> + static String toLiteral(const String &s, StringView ctor = StringView("QStringLiteral")) { - return ctor % u"(\"" % escapeString(s) % u"\")"; + return ctor % StringView("(\"") + % escapeString<String, CharacterLiteral, StringView>(s) % StringView("\")"); } /*! \internal diff --git a/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt b/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt index 7472aa8d37..3eab68a7e7 100644 --- a/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt +++ b/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt @@ -143,6 +143,8 @@ set(qml_sources attachedComponentProperty.qml attachedNamespacedProperty.qml + + newLineTranslation.qml ) set(js_sources diff --git a/tests/auto/qml/qmltc/QmltcTests/newLineTranslation.qml b/tests/auto/qml/qmltc/QmltcTests/newLineTranslation.qml new file mode 100644 index 0000000000..99899e37d4 --- /dev/null +++ b/tests/auto/qml/qmltc/QmltcTests/newLineTranslation.qml @@ -0,0 +1,6 @@ +import QtQml + +QtObject { + objectName: qsTr("Hello World \n") +} + diff --git a/tests/auto/qml/qmltc/tst_qmltc.cpp b/tests/auto/qml/qmltc/tst_qmltc.cpp index 268e213841..73ef03eaaf 100644 --- a/tests/auto/qml/qmltc/tst_qmltc.cpp +++ b/tests/auto/qml/qmltc/tst_qmltc.cpp @@ -97,6 +97,8 @@ #include "attachedcomponentproperty.h" #include "attachednamespacedproperty.h" +#include "newlinetranslation.h" + // Qt: #include <QtCore/qstring.h> #include <QtCore/qbytearray.h> @@ -3455,4 +3457,11 @@ void tst_qmltc::attachedNamespacedProperty() checkOverlayAttached(&createdByQmltc); } +void tst_qmltc::newLineTranslation() +{ + QQmlEngine e; + PREPEND_NAMESPACE(newLineTranslation) createdByQmltc(&e); + QCOMPARE(createdByQmltc.objectName(), "Hello World \n"_L1); +} + QTEST_MAIN(tst_qmltc) diff --git a/tests/auto/qml/qmltc/tst_qmltc.h b/tests/auto/qml/qmltc/tst_qmltc.h index df97a4ec0e..99abb60dc5 100644 --- a/tests/auto/qml/qmltc/tst_qmltc.h +++ b/tests/auto/qml/qmltc/tst_qmltc.h @@ -110,4 +110,6 @@ private slots: void attachedComponentProperty(); void attachedNamespacedProperty(); + + void newLineTranslation(); }; diff --git a/tools/qmltc/qmltccompilerpieces.cpp b/tools/qmltc/qmltccompilerpieces.cpp index 318712999c..ce29045142 100644 --- a/tools/qmltc/qmltccompilerpieces.cpp +++ b/tools/qmltc/qmltccompilerpieces.cpp @@ -253,29 +253,31 @@ void QmltcCodeGenerator::generate_createBindingOnProperty( } } +static QByteArray toLiteral(const QByteArray &utf8) +{ + return QQmlJSUtils::toLiteral<QByteArray, char, QByteArrayView>(utf8); +} + static QString serializeTranslation(const QQmlTranslation::QsTrIdData &data) { - QString result = QStringLiteral(R"(QQmlTranslation(QQmlTranslation::QsTrIdData( - QStringLiteral("%1"), + return QStringLiteral(R"(QQmlTranslation(QQmlTranslation::QsTrIdData( + %1, %4)))") - .arg(QString::fromUtf8(data.id())) - .arg(data.number()); - - return result; + .arg(toLiteral(data.id())) + .arg(data.number()); } static QString serializeTranslation(const QQmlTranslation::QsTrData &data) { - QString result = QStringLiteral(R"(QQmlTranslation(QQmlTranslation::QsTrData( - QStringLiteral("%1"), - QStringLiteral("%2"), - QStringLiteral("%3"), + return QStringLiteral(R"(QQmlTranslation(QQmlTranslation::QsTrData( + %1, + %2, + %3, %4)))") - .arg(QString::fromUtf8(data.context()), QString::fromUtf8(data.text()), - QString::fromUtf8(data.comment())) - .arg(data.number()); - - return result; + .arg(toLiteral(data.context()), + toLiteral(data.text()), + toLiteral(data.comment())) + .arg(data.number()); } static QString serializeTranslation(const QQmlTranslation &translation) |