From 6599c1f75832cc9286a3bf88c6b179d006dbb96e Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 17 Oct 2018 16:22:11 +0200 Subject: QPicture: fix crash for malformed picture A file with the correct QPicture magic bytes, but shorter than a full QPicture file header, could cause the header decoder to access memory out of bounds. Add a size check to avoid. As a driveby, generally harden the parsing against malformed files. [ChangeLog][QtGui][QPicture] Fix crash reading malformed picture file Task-number: QTBUG-71208 Change-Id: I86eb1f915ca9b3a4b91c7433036d76ed6061e2f0 Reviewed-by: Lars Knoll --- src/gui/image/qpicture.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 7aa221948e..7eede5ee26 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -636,7 +636,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) if (d->formatMajor <= 5) { s >> ia >> i_8; painter->drawPolygon(ia, i_8 ? Qt::WindingFill : Qt::OddEvenFill); - a.clear(); + ia.clear(); } else { s >> a >> i_8; painter->drawPolygon(a, i_8 ? Qt::WindingFill : Qt::OddEvenFill); @@ -647,10 +647,10 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) s >> ia; QPainterPath path; Q_ASSERT(ia.size() == 4); - path.moveTo(ia.at(0)); - path.cubicTo(ia.at(1), ia.at(2), ia.at(3)); + path.moveTo(ia.value(0)); + path.cubicTo(ia.value(1), ia.value(2), ia.value(3)); painter->strokePath(path, painter->pen()); - a.clear(); + ia.clear(); } break; case QPicturePrivate::PdcDrawText: @@ -730,7 +730,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int index; s >> r >> index >> sr; Q_ASSERT(index < d->pixmap_list.size()); - pixmap = d->pixmap_list.at(index); + pixmap = d->pixmap_list.value(index); } else { s >> r >> pixmap >> sr; } @@ -744,7 +744,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int index; s >> r >> index >> p; Q_ASSERT(index < d->pixmap_list.size()); - pixmap = d->pixmap_list.at(index); + pixmap = d->pixmap_list.value(index); } else { s >> r >> pixmap >> p; } @@ -765,7 +765,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int index; s >> r >> index >> sr >> ul; Q_ASSERT(index < d->image_list.size()); - image = d->image_list.at(index); + image = d->image_list.value(index); } else { s >> r >> image >> sr >> ul; } @@ -817,7 +817,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int index; s >> index; Q_ASSERT(index < d->pen_list.size()); - pen = d->pen_list.at(index); + pen = d->pen_list.value(index); } else { s >> pen; } @@ -828,7 +828,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int index; s >> index; Q_ASSERT(index < d->brush_list.size()); - brush = d->brush_list.at(index); + brush = d->brush_list.value(index); } else { s >> brush; } @@ -910,7 +910,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) break; default: qWarning("QPicture::play: Invalid command %d", c); - if (len) // skip unknown command + if (len > 0) // skip unknown command s.device()->seek(s.device()->pos()+len); } #if defined(QT_DEBUG) @@ -1075,7 +1075,8 @@ bool QPicturePrivate::checkFormat() char mf_id[4]; // picture header tag s.readRawData(mf_id, 4); // read actual tag - if (memcmp(mf_id, qt_mfhdr_tag, 4) != 0) { // wrong header id + int bufSize = pictb.buffer().size(); + if (memcmp(mf_id, qt_mfhdr_tag, 4) != 0 || bufSize < 12) { // wrong header id or size qWarning("QPicturePaintEngine::checkFormat: Incorrect header"); pictb.close(); return false; -- cgit v1.2.3