Merge remote-tracking branch 'origin/5.7.1' into 5.7

Change-Id: Ic2cdbd0c826bd63f545479495fa095ec666ddd5a
This commit is contained in:
Liang Qi 2016-12-07 12:04:28 +01:00
commit 04f68053df
6 changed files with 35 additions and 13 deletions

View File

@ -786,6 +786,10 @@ static bool readExifHeader(QDataStream &stream)
*/
static int getExifOrientation(QByteArray &exifData)
{
// Current EXIF version (2.3) says there can be at most 5 IFDs,
// byte we allow for 10 so we're able to deal with future extensions.
const int maxIfdCount = 10;
QDataStream stream(&exifData, QIODevice::ReadOnly);
if (!readExifHeader(stream))
@ -793,7 +797,8 @@ static int getExifOrientation(QByteArray &exifData)
quint16 val;
quint32 offset;
const qint64 headerStart = stream.device()->pos();
const qint64 headerStart = 6; // the EXIF header has a constant size
Q_ASSERT(headerStart == stream.device()->pos());
// read byte order marker
stream >> val;
@ -804,7 +809,7 @@ static int getExifOrientation(QByteArray &exifData)
else
return -1; // unknown byte order
// read size
// confirm byte order
stream >> val;
if (val != 0x2a)
return -1;
@ -812,18 +817,22 @@ static int getExifOrientation(QByteArray &exifData)
stream >> offset;
// read IFD
while (!stream.atEnd()) {
for (int n = 0; n < maxIfdCount; ++n) {
quint16 numEntries;
// skip offset bytes to get the next IFD
const qint64 bytesToSkip = offset - (stream.device()->pos() - headerStart);
if (stream.skipRawData(bytesToSkip) != bytesToSkip)
if (bytesToSkip < 0 || (offset + headerStart >= exifData.size())) {
// disallow going backwards, though it's permitted in the spec
return -1;
} else if (bytesToSkip != 0) {
// seek to the IFD
if (!stream.device()->seek(offset + headerStart))
return -1;
}
stream >> numEntries;
for (; numEntries > 0; --numEntries) {
for (; numEntries > 0 && stream.status() == QDataStream::Ok; --numEntries) {
quint16 tag;
quint16 type;
quint32 components;
@ -847,12 +856,14 @@ static int getExifOrientation(QByteArray &exifData)
// read offset to next IFD
stream >> offset;
if (stream.status() != QDataStream::Ok)
return -1;
if (offset == 0) // this is the last IFD
break;
return 0; // No Exif orientation was found
}
// No Exif orientation was found
return 0;
// too many IFDs
return -1;
}
static QImageIOHandler::Transformations exif2Qt(int exifOrientation)

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

View File

@ -183,7 +183,8 @@ private slots:
void exifOrientation();
void exif_QTBUG45865();
void exif_invalid_data_QTBUG46870();
void exifInvalidData_data();
void exifInvalidData();
void cleanupFunctions();
@ -3028,10 +3029,20 @@ void tst_QImage::exif_QTBUG45865()
QCOMPARE(image.size(), QSize(5, 8));
}
void tst_QImage::exif_invalid_data_QTBUG46870()
void tst_QImage::exifInvalidData_data()
{
QTest::addColumn<bool>("$never used");
QTest::newRow("QTBUG-46870");
QTest::newRow("back_pointers");
QTest::newRow("past_end");
QTest::newRow("too_many_ifds");
QTest::newRow("too_many_tags");
}
void tst_QImage::exifInvalidData()
{
QImage image;
QVERIFY(image.load(m_prefix + "jpeg_exif_invalid_data_QTBUG-46870.jpg"));
QVERIFY(image.load(m_prefix + "jpeg_exif_invalid_data_" + QTest::currentDataTag() + ".jpg"));
QVERIFY(!image.isNull());
}