QCosmeticStroker: fix several UBs involving << with a negative LHS
Left-shifts of negative values are undefined in C++. In particular, they don't behave arithmetically. Reported by UBSan: qcosmeticstroker.cpp: 72:15: runtime error: left shift of negative value -14/-19/-32/-33/-34/-37/-38/-63/-64/-192/-384/-1280 qcosmeticstroker.cpp:444:20: runtime error: left shift of negative value -64 qcosmeticstroker.cpp:451:26: runtime error: left shift of negative value -1 qcosmeticstroker.cpp:483:26: runtime error: left shift of negative value -1 qcosmeticstroker.cpp:762:20: runtime error: left shift of negative value -64 qcosmeticstroker.cpp:774:26: runtime error: left shift of negative value -1 qcosmeticstroker.cpp:813:47: runtime error: left shift of negative value -1 qcosmeticstroker.cpp:839:20: runtime error: left shift of negative value -64 qcosmeticstroker.cpp:851:26: runtime error: left shift of negative value -1 qcosmeticstroker.cpp:889:47: runtime error: left shift of negative value -1 qcosmeticstroker.cpp:932:27: runtime error: left shift of negative value -64 qcosmeticstroker.cpp:995:27: runtime error: left shift of negative value -3/-64 Fix by using ordinary multiplication instead, because negative left-hand-side values don't look like they are an error. Change-Id: Icbebd41f6ddd3dca4abd385585fc0f82064fe8b6 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
This commit is contained in:
parent
1a9e1fbbfc
commit
52a599bb56
@ -62,8 +62,8 @@ static inline uint sourceOver(uint d, uint color)
|
||||
inline static int F16Dot16FixedDiv(int x, int y)
|
||||
{
|
||||
if (qAbs(x) > 0x7fff)
|
||||
return (((qlonglong)x) << 16) / y;
|
||||
return (x << 16) / y;
|
||||
return qlonglong(x) * (1<<16) / y;
|
||||
return x * (1<<16) / y;
|
||||
}
|
||||
|
||||
typedef void (*DrawPixel)(QCosmeticStroker *stroker, int x, int y, int coverage);
|
||||
@ -435,14 +435,14 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
|
||||
qSwap(x1, x2);
|
||||
}
|
||||
int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
|
||||
int x = x1 << 10;
|
||||
int x = x1 * (1<<10);
|
||||
|
||||
int y = (y1 + 32) >> 6;
|
||||
int ys = (y2 + 32) >> 6;
|
||||
|
||||
int round = (xinc > 0) ? 32 : 0;
|
||||
if (y != ys) {
|
||||
x += ( ((((y << 6) + round - y1))) * xinc ) >> 6;
|
||||
x += ((y * (1<<6)) + round - y1) * xinc >> 6;
|
||||
|
||||
if (swapped) {
|
||||
lastPixel.x = x >> 16;
|
||||
@ -474,7 +474,7 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
|
||||
|
||||
int round = (yinc > 0) ? 32 : 0;
|
||||
if (x != xs) {
|
||||
y += ( ((((x << 6) + round - x1))) * yinc ) >> 6;
|
||||
y += ((x * (1<<6)) + round - x1) * yinc >> 6;
|
||||
|
||||
if (swapped) {
|
||||
lastPixel.x = x;
|
||||
@ -753,7 +753,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
|
||||
dir = QCosmeticStroker::BottomToTop;
|
||||
}
|
||||
int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
|
||||
int x = x1 << 10;
|
||||
int x = x1 * (1<<10);
|
||||
|
||||
if ((stroker->lastDir ^ QCosmeticStroker::VerticalMask) == dir)
|
||||
caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
|
||||
@ -765,7 +765,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
|
||||
int round = (xinc > 0) ? 32 : 0;
|
||||
|
||||
if (y != ys) {
|
||||
x += ( ((((y << 6) + round - y1))) * xinc ) >> 6;
|
||||
x += ((y * (1<<6)) + round - y1) * xinc >> 6;
|
||||
|
||||
// calculate first and last pixel and perform dropout control
|
||||
QCosmeticStroker::Point first;
|
||||
@ -804,7 +804,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
|
||||
stroker->lastDir = dir;
|
||||
stroker->lastAxisAligned = axisAligned;
|
||||
|
||||
Dasher dasher(stroker, swapped, y << 6, ys << 6);
|
||||
Dasher dasher(stroker, swapped, y * (1<<6), ys * (1<<6));
|
||||
|
||||
do {
|
||||
if (dasher.on())
|
||||
@ -830,7 +830,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
|
||||
dir = QCosmeticStroker::RightToLeft;
|
||||
}
|
||||
int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1);
|
||||
int y = y1 << 10;
|
||||
int y = y1 * (1<<10);
|
||||
|
||||
if ((stroker->lastDir ^ QCosmeticStroker::HorizontalMask) == dir)
|
||||
caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
|
||||
@ -842,7 +842,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
|
||||
int round = (yinc > 0) ? 32 : 0;
|
||||
|
||||
if (x != xs) {
|
||||
y += ( ((((x << 6) + round - x1))) * yinc ) >> 6;
|
||||
y += ((x * (1<<6)) + round - x1) * yinc >> 6;
|
||||
|
||||
// calculate first and last pixel to perform dropout control
|
||||
QCosmeticStroker::Point first;
|
||||
@ -880,7 +880,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
|
||||
stroker->lastDir = dir;
|
||||
stroker->lastAxisAligned = axisAligned;
|
||||
|
||||
Dasher dasher(stroker, swapped, x << 6, xs << 6);
|
||||
Dasher dasher(stroker, swapped, x * (1<<6), xs * (1<<6));
|
||||
|
||||
do {
|
||||
if (dasher.on())
|
||||
@ -923,7 +923,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
|
||||
caps = swapCaps(caps);
|
||||
}
|
||||
|
||||
int x = (x1 - 32) << 10;
|
||||
int x = (x1 - 32) * (1<<10);
|
||||
x -= ( ((y1 & 63) - 32) * xinc ) >> 6;
|
||||
|
||||
capAdjust(caps, y1, y2, x, xinc);
|
||||
@ -986,7 +986,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
|
||||
caps = swapCaps(caps);
|
||||
}
|
||||
|
||||
int y = (y1 - 32) << 10;
|
||||
int y = (y1 - 32) * (1<<10);
|
||||
y -= ( ((x1 & 63) - 32) * yinc ) >> 6;
|
||||
|
||||
capAdjust(caps, x1, x2, y, yinc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user