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:
parent
cfcfe7d07b
commit
b45d7cc24c
@ -2653,14 +2653,14 @@ QTextEngine::LayoutData::LayoutData()
|
|||||||
currentMaxWidth = 0;
|
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)
|
: string(str)
|
||||||
{
|
{
|
||||||
allocated = _allocated;
|
allocated = _allocated;
|
||||||
|
|
||||||
qsizetype space_charAttributes = sizeof(QCharAttributes) * string.size() / sizeof(void*) + 1;
|
int space_charAttributes = int(sizeof(QCharAttributes) * string.size() / sizeof(void*) + 1);
|
||||||
qsizetype space_logClusters = sizeof(unsigned short) * string.size() / sizeof(void*) + 1;
|
int space_logClusters = int(sizeof(unsigned short) * string.size() / sizeof(void*) + 1);
|
||||||
available_glyphs = (allocated - space_charAttributes - space_logClusters) * sizeof(void*) / QGlyphLayout::SpaceNeeded;
|
available_glyphs = ((int)allocated - space_charAttributes - space_logClusters)*(int)sizeof(void*)/(int)QGlyphLayout::SpaceNeeded;
|
||||||
|
|
||||||
if (available_glyphs < str.size()) {
|
if (available_glyphs < str.size()) {
|
||||||
// need to allocate on the heap
|
// need to allocate on the heap
|
||||||
@ -2701,16 +2701,15 @@ bool QTextEngine::LayoutData::reallocate(int totalGlyphs)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qsizetype space_charAttributes = (sizeof(QCharAttributes) * string.size() / sizeof(void*) + 1);
|
int space_charAttributes = int(sizeof(QCharAttributes) * string.size() / sizeof(void*) + 1);
|
||||||
const qsizetype space_logClusters = (sizeof(unsigned short) * string.size() / sizeof(void*) + 1);
|
int space_logClusters = int(sizeof(unsigned short) * string.size() / sizeof(void*) + 1);
|
||||||
const qsizetype space_glyphs = qsizetype(totalGlyphs) * QGlyphLayout::SpaceNeeded / sizeof(void *) + 2;
|
int space_glyphs = (totalGlyphs * QGlyphLayout::SpaceNeeded) / sizeof(void *) + 2;
|
||||||
|
|
||||||
const qsizetype newAllocated = space_charAttributes + space_glyphs + space_logClusters;
|
int newAllocated = space_charAttributes + space_glyphs + space_logClusters;
|
||||||
// Check if the length of string/glyphs causes int overflow,
|
// 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
|
// we can't layout such a long string all at once, so return false here to
|
||||||
// indicate there is a failure
|
// indicate there is a failure
|
||||||
if (size_t(space_charAttributes) > INT_MAX || size_t(space_logClusters) > INT_MAX || totalGlyphs < 0
|
if (space_charAttributes < 0 || space_logClusters < 0 || space_glyphs < 0 || newAllocated < allocated) {
|
||||||
|| size_t(space_glyphs) > INT_MAX || size_t(newAllocated) > INT_MAX || newAllocated < allocated) {
|
|
||||||
layoutState = LayoutFailed;
|
layoutState = LayoutFailed;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2730,7 +2729,7 @@ bool QTextEngine::LayoutData::reallocate(int totalGlyphs)
|
|||||||
logClustersPtr = (unsigned short *) m;
|
logClustersPtr = (unsigned short *) m;
|
||||||
m += space_logClusters;
|
m += space_logClusters;
|
||||||
|
|
||||||
const qsizetype space_preGlyphLayout = space_charAttributes + space_logClusters;
|
const int space_preGlyphLayout = space_charAttributes + space_logClusters;
|
||||||
if (allocated < space_preGlyphLayout)
|
if (allocated < space_preGlyphLayout)
|
||||||
memset(memory + allocated, 0, (space_preGlyphLayout - allocated)*sizeof(void *));
|
memset(memory + allocated, 0, (space_preGlyphLayout - allocated)*sizeof(void *));
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ struct QGlyphLayout
|
|||||||
inline explicit QGlyphLayout(char *address, int totalGlyphs)
|
inline explicit QGlyphLayout(char *address, int totalGlyphs)
|
||||||
{
|
{
|
||||||
offsets = reinterpret_cast<QFixedPoint *>(address);
|
offsets = reinterpret_cast<QFixedPoint *>(address);
|
||||||
qsizetype offset = totalGlyphs * sizeof(QFixedPoint);
|
int offset = totalGlyphs * sizeof(QFixedPoint);
|
||||||
glyphs = reinterpret_cast<glyph_t *>(address + offset);
|
glyphs = reinterpret_cast<glyph_t *>(address + offset);
|
||||||
offset += totalGlyphs * sizeof(glyph_t);
|
offset += totalGlyphs * sizeof(glyph_t);
|
||||||
advances = reinterpret_cast<QFixed *>(address + offset);
|
advances = reinterpret_cast<QFixed *>(address + offset);
|
||||||
@ -211,7 +211,7 @@ struct QGlyphLayout
|
|||||||
last = numGlyphs;
|
last = numGlyphs;
|
||||||
if (first == 0 && last == numGlyphs
|
if (first == 0 && last == numGlyphs
|
||||||
&& reinterpret_cast<char *>(offsets + numGlyphs) == reinterpret_cast<char *>(glyphs)) {
|
&& 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 {
|
} else {
|
||||||
const int num = last - first;
|
const int num = last - first;
|
||||||
memset(static_cast<void *>(offsets + first), 0, num * sizeof(QFixedPoint));
|
memset(static_cast<void *>(offsets + first), 0, num * sizeof(QFixedPoint));
|
||||||
@ -372,12 +372,12 @@ public:
|
|||||||
LayoutFailed
|
LayoutFailed
|
||||||
};
|
};
|
||||||
struct Q_GUI_EXPORT LayoutData {
|
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();
|
||||||
~LayoutData();
|
~LayoutData();
|
||||||
mutable QScriptItemArray items;
|
mutable QScriptItemArray items;
|
||||||
qsizetype allocated;
|
int allocated;
|
||||||
qsizetype available_glyphs;
|
int available_glyphs;
|
||||||
void **memory;
|
void **memory;
|
||||||
unsigned short *logClustersPtr;
|
unsigned short *logClustersPtr;
|
||||||
QGlyphLayout glyphLayout;
|
QGlyphLayout glyphLayout;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user