summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-thai.c9
-rw-r--r--tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp24
2 files changed, 30 insertions, 3 deletions
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-thai.c b/src/3rdparty/harfbuzz/src/harfbuzz-thai.c
index bf6c35b19c..3c0ffe8358 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-thai.c
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-thai.c
@@ -263,8 +263,13 @@ static HB_Bool HB_ThaiConvertStringToGlyphIndices (HB_ShaperItem *item)
// The only glyphs that should be passed to this function that cannot be mapped to
// tis620 are the ones of type Inherited class. Pass these glyphs untouched.
glyphString[slen++] = string[i];
- if (string[i] == 0x200D || string[i] == 0x200C)
- item->attributes[slen-1].dontPrint = true; // Hide ZWJ and ZWNJ characters
+ if (string[i] == 0x200D || string[i] == 0x200C) {
+ // Check that we do not run out of bounds when setting item->attributes. If we do
+ // run out of bounds then this function will return false, the necessary amount of
+ // memory is reallocated, and this function will then be called again.
+ if (slen <= item->num_glyphs)
+ item->attributes[slen-1].dontPrint = true; // Hide ZWJ and ZWNJ characters
+ }
} else {
glyphString[slen++] = (HB_UChar16) thai_get_glyph_index (font_type, rglyphs[lgi]);
}
diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
index a88e93c93e..d566f0a20d 100644
--- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
+++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
@@ -105,7 +105,7 @@ private slots:
void thaiIsolatedSaraAm();
void thaiWithZWJ();
-
+ void thaiMultipleVowels();
private:
bool haveTestFonts;
};
@@ -1325,5 +1325,27 @@ void tst_QTextScriptEngine::thaiWithZWJ()
QCOMPARE((bool)e->layoutData->glyphLayout.attributes[i].dontPrint, (i == 1 || i == 3));
}
+void tst_QTextScriptEngine::thaiMultipleVowels()
+{
+ QString s(QString::fromUtf8("ส"));
+ for (int i = 0; i < 100; i++)
+ s += QChar(0x0E47); // Add lots of "VOWEL SIGN MAI TAI KHU N/S-T" stacked on top of the character
+ s += QChar(0x200D); // Now add a zero width joiner (which adds a circle which is hidden)
+ for (int i = 0; i < 100; i++)
+ s += QChar(0x0E47); //Add lots of "VOWEL SIGN MAI TAI KHU N/S-T" stacked on top of the ZWJ
+
+ for (int i = 0; i < 10; i++)
+ s += s; //Repeat the string to make it more likely to crash if we have a buffer overflow
+ QTextLayout layout(s);
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QTextEngine *e = layout.engine();
+ e->width(0, s.length()); //force itemize and shape
+
+ // If we haven't crashed at this point, then the test has passed.
+}
+
QTEST_MAIN(tst_QTextScriptEngine)
#include "tst_qtextscriptengine.moc"