summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@digia.com>2012-12-14 10:52:47 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-12-14 17:12:44 +0100
commit52619ae7787b3c4febb73a02afa623b12edabc97 (patch)
tree6a2d25bfbe59a1ca73c37bddf82ee11fbe8037c9
parent7ca226c9512e8f1d11e428b24e9f91c81ad4cbe7 (diff)
Fixed invalid memory read in SSSE3 image blending code.
We need to do bounds comparison on the actual offset we're going to use with _mm_load_si128 to read 16 bytes from memory (even though we won't use the trailing bytes in the end). Task-number: QTBUG-28324 Change-Id: Id0d6094da796ca67338d8ad225fa6b2f309bbe6e Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
-rw-r--r--src/gui/painting/qdrawhelper_ssse3.cpp2
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp20
2 files changed, 21 insertions, 1 deletions
diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp
index 09e0516dcb..9f80c70fcc 100644
--- a/src/gui/painting/qdrawhelper_ssse3.cpp
+++ b/src/gui/painting/qdrawhelper_ssse3.cpp
@@ -60,7 +60,7 @@ inline static void blend_pixel(quint32 &dst, const quint32 src)
shift (4, 8, 12). Checking the alignment inside the loop is unfortunatelly way too slow.
*/
#define BLENDING_LOOP(palignrOffset, length)\
- for (; x < length-3; x += 4) { \
+ for (; x-minusOffsetToAlignSrcOn16Bytes < length-7; x += 4) { \
const __m128i srcVectorLastLoaded = _mm_load_si128((__m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes + 4]);\
const __m128i srcVector = _mm_alignr_epi8(srcVectorLastLoaded, srcVectorPrevLoaded, palignrOffset); \
const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
index 51c261fc6a..085aef6019 100644
--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -229,6 +229,7 @@ private slots:
void drawImage_task217400();
void drawImage_1x1();
void drawImage_task258776();
+ void drawImage_QTBUG28324();
void drawRect_task215378();
void drawRect_task247505();
@@ -3233,6 +3234,25 @@ void tst_QPainter::drawImage_task258776()
QCOMPARE(dest, expected);
}
+void tst_QPainter::drawImage_QTBUG28324()
+{
+ QImage dest(512, 512, QImage::Format_ARGB32_Premultiplied);
+ dest.fill(0x0);
+
+ int x = 263; int y = 89; int w = 61; int h = 39;
+
+ QImage source(w, h, QImage::Format_ARGB32_Premultiplied);
+ quint32 *b = (quint32 *)source.bits();
+ for (int j = 0; j < w * h; ++j)
+ b[j] = 0x7f7f7f7f;
+
+ // nothing to test here since the bug is about
+ // an invalid memory read, which valgrind
+ // would complain about
+ QPainter p(&dest);
+ p.drawImage(x, y, source);
+}
+
void tst_QPainter::clipRectSaveRestore()
{
QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);