Fix crash when text contains too many directional chars
In case a text to be layouted contains more than 128 directional characters it causes the application to crash The function initScriptAnalysisAndIsolatePairs() collects information of RTL/LTR chaaracters into vector "isolatePairs". The size of the vector is capped to 128. Later the function generateDirectionalRuns() iterates the text again and tries to access items from the previously capped vector above the upper bound. Task-number: QTBUG-77819 Change-Id: Ibb7bf12c12b1db22f43ff46236518da3fdeed26a Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> (cherry picked from commit 1232205e32464d90e871f39eb1e14fcf9b78a163) Reviewed-by: Jukka Jokiniva <jukka.jokiniva@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
97465b1540
commit
af6ac444c9
@ -399,6 +399,7 @@ struct QBidiAlgorithm {
|
|||||||
analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL;
|
analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL;
|
||||||
runHasContent = true;
|
runHasContent = true;
|
||||||
lastRunWithContent = -1;
|
lastRunWithContent = -1;
|
||||||
|
++isolatePairPosition;
|
||||||
}
|
}
|
||||||
int runBeforeIsolate = runs.size();
|
int runBeforeIsolate = runs.size();
|
||||||
ushort newLevel = isRtl ? ((stack.top().level + 1) | 1) : ((stack.top().level + 2) & ~1);
|
ushort newLevel = isRtl ? ((stack.top().level + 1) | 1) : ((stack.top().level + 2) & ~1);
|
||||||
@ -440,21 +441,19 @@ struct QBidiAlgorithm {
|
|||||||
doEmbed(true, true, false);
|
doEmbed(true, true, false);
|
||||||
break;
|
break;
|
||||||
case QChar::DirLRI:
|
case QChar::DirLRI:
|
||||||
Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
|
|
||||||
doEmbed(false, false, true);
|
doEmbed(false, false, true);
|
||||||
++isolatePairPosition;
|
|
||||||
break;
|
break;
|
||||||
case QChar::DirRLI:
|
case QChar::DirRLI:
|
||||||
Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
|
|
||||||
doEmbed(true, false, true);
|
doEmbed(true, false, true);
|
||||||
++isolatePairPosition;
|
|
||||||
break;
|
break;
|
||||||
case QChar::DirFSI: {
|
case QChar::DirFSI: {
|
||||||
|
bool isRtl = false;
|
||||||
|
if (isolatePairPosition < isolatePairs.size()) {
|
||||||
const auto &pair = isolatePairs.at(isolatePairPosition);
|
const auto &pair = isolatePairs.at(isolatePairPosition);
|
||||||
Q_ASSERT(pair.start == i);
|
Q_ASSERT(pair.start == i);
|
||||||
bool isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
|
isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
|
||||||
|
}
|
||||||
doEmbed(isRtl, false, true);
|
doEmbed(isRtl, false, true);
|
||||||
++isolatePairPosition;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@ private slots:
|
|||||||
void noModificationOfInputString();
|
void noModificationOfInputString();
|
||||||
void superscriptCrash_qtbug53911();
|
void superscriptCrash_qtbug53911();
|
||||||
void showLineAndParagraphSeparatorsCrash();
|
void showLineAndParagraphSeparatorsCrash();
|
||||||
|
void tooManyDirectionalCharctersCrash_qtbug77819();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QFont testFont;
|
QFont testFont;
|
||||||
@ -2309,5 +2310,21 @@ void tst_QTextLayout::nbspWithFormat()
|
|||||||
QCOMPARE(layout.lineAt(1).textLength(), s2.length() + 1 + s3.length());
|
QCOMPARE(layout.lineAt(1).textLength(), s2.length() + 1 + s3.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QTextLayout::tooManyDirectionalCharctersCrash_qtbug77819()
|
||||||
|
{
|
||||||
|
QString data;
|
||||||
|
data += QString::fromUtf8("\xe2\x81\xa8"); // U+2068 FSI character
|
||||||
|
data += QString::fromUtf8("\xe2\x81\xa7"); // U+2067 RLI character
|
||||||
|
|
||||||
|
// duplicating the text
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
data += data;
|
||||||
|
|
||||||
|
// Nothing to test. It must not crash in beginLayout().
|
||||||
|
QTextLayout tl(data);
|
||||||
|
tl.beginLayout();
|
||||||
|
tl.endLayout();
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QTextLayout)
|
QTEST_MAIN(tst_QTextLayout)
|
||||||
#include "tst_qtextlayout.moc"
|
#include "tst_qtextlayout.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user