Merge remote-tracking branch 'origin/5.7.1' into 5.7
Change-Id: Ic2cdbd0c826bd63f545479495fa095ec666ddd5a
This commit is contained in:
commit
04f68053df
@ -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 |
@ -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());
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user