summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucie Gerard <lucie.gerard@qt.io>2019-04-03 09:02:35 +0200
committerLucie Gerard <lucie.gerard@qt.io>2019-04-03 07:09:38 +0000
commit3d095069cf2e2e349489bcf5faf92145320471fb (patch)
tree9e09badc10713851f568a9a6cf163da03f57b615
parentb8a6084861456f5448c0fd0c22e0192e83ffb5f0 (diff)
lupdate: Escape special characters when processing QML
The transcode function is now in a parser tool class. It is used by the cpp and qml parser. Fixes: QTBUG-40639 Change-Id: I3c9c9d137669900642a077cf81a739bfc31be800 Reviewed-by: Kai Koehne <kai.koehne@qt.io>
-rw-r--r--src/linguist/lupdate/cpp.cpp66
-rw-r--r--src/linguist/lupdate/lupdate.h5
-rw-r--r--src/linguist/lupdate/main.cpp51
-rw-r--r--src/linguist/lupdate/qdeclarative.cpp12
4 files changed, 69 insertions, 65 deletions
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp
index d8a4f9a37..e96e102af 100644
--- a/src/linguist/lupdate/cpp.cpp
+++ b/src/linguist/lupdate/cpp.cpp
@@ -250,7 +250,6 @@ private:
bool matchStringOrNull(QString *s);
bool matchExpression();
- QString transcode(const QString &str);
void recordMessage(
int line, const QString &context, const QString &text, const QString &comment,
const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
@@ -1469,7 +1468,7 @@ bool CppParser::matchString(QString *s)
return matches;
matches = true;
if (yyTok == Tok_String)
- *s += transcode(yyWord);
+ *s += ParserTool::transcode(yyWord);
else
*s += yyWord;
s->detach();
@@ -1550,65 +1549,14 @@ bool CppParser::matchExpression()
return true;
}
-QString CppParser::transcode(const QString &str)
-{
- static const char tab[] = "abfnrtv";
- static const char backTab[] = "\a\b\f\n\r\t\v";
- // This function has to convert back to bytes, as C's \0* sequences work at that level.
- const QByteArray in = str.toUtf8();
- QByteArray out;
-
- out.reserve(in.length());
- for (int i = 0; i < in.length();) {
- uchar c = in[i++];
- if (c == '\\') {
- if (i >= in.length())
- break;
- c = in[i++];
-
- if (c == '\n')
- continue;
-
- if (c == 'x' || c == 'u' || c == 'U') {
- const bool unicode = (c != 'x');
- QByteArray hex;
- while (i < in.length() && isxdigit((c = in[i]))) {
- hex += c;
- i++;
- }
- if (unicode)
- out += QString(QChar(hex.toUInt(nullptr, 16))).toUtf8();
- else
- out += hex.toUInt(nullptr, 16);
- } else if (c >= '0' && c < '8') {
- QByteArray oct;
- int n = 0;
- oct += c;
- while (n < 2 && i < in.length() && (c = in[i]) >= '0' && c < '8') {
- i++;
- n++;
- oct += c;
- }
- out += oct.toUInt(0, 8);
- } else {
- const char *p = strchr(tab, c);
- out += !p ? c : backTab[p - tab];
- }
- } else {
- out += c;
- }
- }
- return QString::fromUtf8(out.constData(), out.length());
-}
-
void CppParser::recordMessage(int line, const QString &context, const QString &text, const QString &comment,
const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, bool plural)
{
TranslatorMessage msg(
- transcode(context), text, transcode(comment), QString(),
+ ParserTool::transcode(context), text, ParserTool::transcode(comment), QString(),
yyFileName, line, QStringList(),
TranslatorMessage::Unfinished, plural);
- msg.setExtraComment(transcode(extracomment.simplified()));
+ msg.setExtraComment(ParserTool::transcode(extracomment.simplified()));
msg.setId(msgid);
msg.setExtras(extra);
tor->append(msg);
@@ -1778,7 +1726,7 @@ void CppParser::handleTrId(bool plural)
yyTok = getToken();
if (matchString(&msgid) && !msgid.isEmpty()) {
plural |= match(Tok_Comma);
- recordMessage(line, QString(), transcode(sourcetext), QString(), extracomment,
+ recordMessage(line, QString(), ParserTool::transcode(sourcetext), QString(), extracomment,
msgid, extra, plural);
}
sourcetext.clear();
@@ -2335,11 +2283,11 @@ void CppParser::processComment()
context = comment.left(k);
comment.remove(0, k + 1);
TranslatorMessage msg(
- transcode(context), QString(),
- transcode(comment), QString(),
+ ParserTool::transcode(context), QString(),
+ ParserTool::transcode(comment), QString(),
yyFileName, yyLineNo, QStringList(),
TranslatorMessage::Finished, false);
- msg.setExtraComment(transcode(extracomment.simplified()));
+ msg.setExtraComment(ParserTool::transcode(extracomment.simplified()));
extracomment.clear();
tor->append(msg);
tor->setExtras(extra);
diff --git a/src/linguist/lupdate/lupdate.h b/src/linguist/lupdate/lupdate.h
index 0d98379d0..bb58cbd1e 100644
--- a/src/linguist/lupdate/lupdate.h
+++ b/src/linguist/lupdate/lupdate.h
@@ -99,6 +99,11 @@ bool loadQml(Translator &translator, const QString &filename, ConversionData &cd
UNARY_MACRO(qsTranslate) \
/*end*/
+class ParserTool
+{
+public:
+ static QString transcode(const QString &str);
+};
class TrFunctionAliasManager {
public:
diff --git a/src/linguist/lupdate/main.cpp b/src/linguist/lupdate/main.cpp
index ba1126aa7..c6b026dc7 100644
--- a/src/linguist/lupdate/main.cpp
+++ b/src/linguist/lupdate/main.cpp
@@ -136,6 +136,57 @@ QStringList TrFunctionAliasManager::availableFunctionsWithAliases() const
TrFunctionAliasManager trFunctionAliasManager;
+QString ParserTool::transcode(const QString &str)
+{
+ static const char tab[] = "abfnrtv";
+ static const char backTab[] = "\a\b\f\n\r\t\v";
+ // This function has to convert back to bytes, as C's \0* sequences work at that level.
+ const QByteArray in = str.toUtf8();
+ QByteArray out;
+
+ out.reserve(in.length());
+ for (int i = 0; i < in.length();) {
+ uchar c = in[i++];
+ if (c == '\\') {
+ if (i >= in.length())
+ break;
+ c = in[i++];
+
+ if (c == '\n')
+ continue;
+
+ if (c == 'x' || c == 'u' || c == 'U') {
+ const bool unicode = (c != 'x');
+ QByteArray hex;
+ while (i < in.length() && isxdigit((c = in[i]))) {
+ hex += c;
+ i++;
+ }
+ if (unicode)
+ out += QString(QChar(hex.toUInt(nullptr, 16))).toUtf8();
+ else
+ out += hex.toUInt(nullptr, 16);
+ } else if (c >= '0' && c < '8') {
+ QByteArray oct;
+ int n = 0;
+ oct += c;
+ while (n < 2 && i < in.length() && (c = in[i]) >= '0' && c < '8') {
+ i++;
+ n++;
+ oct += c;
+ }
+ out += oct.toUInt(0, 8);
+ } else {
+ const char *p = strchr(tab, c);
+ out += !p ? c : backTab[p - tab];
+ }
+ } else {
+ out += c;
+ }
+ }
+ return QString::fromUtf8(out.constData(), out.length());
+}
+
static QString m_defaultExtensions;
static void printOut(const QString & out)
diff --git a/src/linguist/lupdate/qdeclarative.cpp b/src/linguist/lupdate/qdeclarative.cpp
index 69164add2..fa8ad260e 100644
--- a/src/linguist/lupdate/qdeclarative.cpp
+++ b/src/linguist/lupdate/qdeclarative.cpp
@@ -130,11 +130,11 @@ protected:
if (!sourcetext.isEmpty())
yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name));
- TranslatorMessage msg(m_component, source,
+ TranslatorMessage msg(m_component, ParserTool::transcode(source),
comment, QString(), m_fileName,
node->firstSourceLocation().startLine, QStringList(),
TranslatorMessage::Unfinished, plural);
- msg.setExtraComment(extracomment.simplified());
+ msg.setExtraComment(ParserTool::transcode(extracomment.simplified()));
msg.setId(msgid);
msg.setExtras(extra);
m_translator->extend(msg, m_cd);
@@ -171,11 +171,11 @@ protected:
plural = true;
}
- TranslatorMessage msg(context, source,
+ TranslatorMessage msg(context, ParserTool::transcode(source),
comment, QString(), m_fileName,
node->firstSourceLocation().startLine, QStringList(),
TranslatorMessage::Unfinished, plural);
- msg.setExtraComment(extracomment.simplified());
+ msg.setExtraComment(ParserTool::transcode(extracomment.simplified()));
msg.setId(msgid);
msg.setExtras(extra);
m_translator->extend(msg, m_cd);
@@ -199,11 +199,11 @@ protected:
bool plural = node->arguments->next;
- TranslatorMessage msg(QString(), sourcetext,
+ TranslatorMessage msg(QString(), ParserTool::transcode(sourcetext),
QString(), QString(), m_fileName,
node->firstSourceLocation().startLine, QStringList(),
TranslatorMessage::Unfinished, plural);
- msg.setExtraComment(extracomment.simplified());
+ msg.setExtraComment(ParserTool::transcode(extracomment.simplified()));
msg.setId(id);
msg.setExtras(extra);
m_translator->extend(msg, m_cd);