Revert "QTextEngine: Protect against integer overflow with huge texts"

This change introduced a regression for the case where the string is
just a little bit too large.

This reverts commit 79ac8b110ae998ad2545238536cb254197540b57.

Task-number: QTBUG-123339
Change-Id: I7b629450d88421201919d82a433d973f76328509
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
Paul Olav Tvete 2024-03-15 10:37:27 +01:00
parent cfcfe7d07b
commit b45d7cc24c
2 changed files with 16 additions and 17 deletions

View File

@ -2653,14 +2653,14 @@ QTextEngine::LayoutData::LayoutData()
currentMaxWidth = 0;
}
QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, qsizetype _allocated)
QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int _allocated)
: string(str)
{
allocated = _allocated;
qsizetype space_charAttributes = sizeof(QCharAttributes) * string.size() / sizeof(void*) + 1;
qsizetype space_logClusters = sizeof(unsigned short) * string.size() / sizeof(void*) + 1;
available_glyphs = (allocated - space_charAttributes - space_logClusters) * sizeof(void*) / QGlyphLayout::SpaceNeeded;
int space_charAttributes = int(sizeof(QCharAttributes) * string.size() / sizeof(void*) + 1);
int space_logClusters = int(sizeof(unsigned short) * string.size() / sizeof(void*) + 1);
available_glyphs = ((int)allocated - space_charAttributes - space_logClusters)*(int)sizeof(void*)/(int)QGlyphLayout::SpaceNeeded;
if (available_glyphs < str.size()) {
// need to allocate on the heap
@ -2701,16 +2701,15 @@ bool QTextEngine::LayoutData::reallocate(int totalGlyphs)
return true;
}
const qsizetype space_charAttributes = (sizeof(QCharAttributes) * string.size() / sizeof(void*) + 1);
const qsizetype space_logClusters = (sizeof(unsigned short) * string.size() / sizeof(void*) + 1);
const qsizetype space_glyphs = qsizetype(totalGlyphs) * QGlyphLayout::SpaceNeeded / sizeof(void *) + 2;
int space_charAttributes = int(sizeof(QCharAttributes) * string.size() / sizeof(void*) + 1);
int space_logClusters = int(sizeof(unsigned short) * string.size() / sizeof(void*) + 1);
int space_glyphs = (totalGlyphs * QGlyphLayout::SpaceNeeded) / sizeof(void *) + 2;
const qsizetype newAllocated = space_charAttributes + space_glyphs + space_logClusters;
// Check if the length of string/glyphs causes int overflow,
int newAllocated = space_charAttributes + space_glyphs + space_logClusters;
// These values can be negative if the length of string/glyphs causes overflow,
// we can't layout such a long string all at once, so return false here to
// indicate there is a failure
if (size_t(space_charAttributes) > INT_MAX || size_t(space_logClusters) > INT_MAX || totalGlyphs < 0
|| size_t(space_glyphs) > INT_MAX || size_t(newAllocated) > INT_MAX || newAllocated < allocated) {
if (space_charAttributes < 0 || space_logClusters < 0 || space_glyphs < 0 || newAllocated < allocated) {
layoutState = LayoutFailed;
return false;
}
@ -2730,7 +2729,7 @@ bool QTextEngine::LayoutData::reallocate(int totalGlyphs)
logClustersPtr = (unsigned short *) m;
m += space_logClusters;
const qsizetype space_preGlyphLayout = space_charAttributes + space_logClusters;
const int space_preGlyphLayout = space_charAttributes + space_logClusters;
if (allocated < space_preGlyphLayout)
memset(memory + allocated, 0, (space_preGlyphLayout - allocated)*sizeof(void *));

View File

@ -178,7 +178,7 @@ struct QGlyphLayout
inline explicit QGlyphLayout(char *address, int totalGlyphs)
{
offsets = reinterpret_cast<QFixedPoint *>(address);
qsizetype offset = totalGlyphs * sizeof(QFixedPoint);
int offset = totalGlyphs * sizeof(QFixedPoint);
glyphs = reinterpret_cast<glyph_t *>(address + offset);
offset += totalGlyphs * sizeof(glyph_t);
advances = reinterpret_cast<QFixed *>(address + offset);
@ -211,7 +211,7 @@ struct QGlyphLayout
last = numGlyphs;
if (first == 0 && last == numGlyphs
&& reinterpret_cast<char *>(offsets + numGlyphs) == reinterpret_cast<char *>(glyphs)) {
memset(static_cast<void *>(offsets), 0, qsizetype(numGlyphs) * SpaceNeeded);
memset(static_cast<void *>(offsets), 0, (numGlyphs * SpaceNeeded));
} else {
const int num = last - first;
memset(static_cast<void *>(offsets + first), 0, num * sizeof(QFixedPoint));
@ -372,12 +372,12 @@ public:
LayoutFailed
};
struct Q_GUI_EXPORT LayoutData {
LayoutData(const QString &str, void **stack_memory, qsizetype mem_size);
LayoutData(const QString &str, void **stack_memory, int mem_size);
LayoutData();
~LayoutData();
mutable QScriptItemArray items;
qsizetype allocated;
qsizetype available_glyphs;
int allocated;
int available_glyphs;
void **memory;
unsigned short *logClustersPtr;
QGlyphLayout glyphLayout;