Merge pull request #256 from piponazo/fix253

Fix for #253
v0.27.3
D4N 7 years ago committed by GitHub
commit 314d2f91a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -30,6 +30,7 @@
#include "image_int.hpp"
#include "error.hpp"
#include "futils.hpp"
#include "enforce.hpp"
#ifdef WIN32
#include <windows.h>
@ -324,12 +325,14 @@ namespace Exiv2 {
int c = -1;
// Skips potential padding between markers
while ((c=io_->getb()) != 0xff) {
if (c == EOF) return -1;
if (c == EOF)
return -1;
}
// Markers can start with any number of 0xff
while ((c=io_->getb()) == 0xff) {
if (c == EOF) return -2;
if (c == EOF)
return -2;
}
return c;
}
@ -562,10 +565,12 @@ namespace Exiv2 {
void JpegBase::printStructure(std::ostream& out, PrintStructureOption option, int depth)
{
if (io_->open() != 0) throw Error(kerDataSourceOpenFailed, io_->path(), strError());
if (io_->open() != 0)
throw Error(kerDataSourceOpenFailed, io_->path(), strError());
// Ensure that this is the correct image type
if (!isThisType(*io_, false)) {
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
throw Error(kerNotAJpeg);
}
@ -573,7 +578,6 @@ namespace Exiv2 {
Exiv2::Uint32Vector iptcDataSegs;
if (bPrint || option == kpsXMP || option == kpsIccProfile || option == kpsIptcErase) {
// nmonic for markers
std::string nm[256];
nm[0xd8] = "SOI";
@ -599,11 +603,8 @@ namespace Exiv2 {
// which markers have a length field?
bool mHasLength[256];
for (int i = 0; i < 256; i++)
mHasLength[i]
= ( i >= sof0_ && i <= sof15_)
|| ( i >= app0_ && i <= (app0_ | 0x0F))
|| ( i == dht_ || i == dqt_ || i == dri_ || i == com_ || i == sos_ )
;
mHasLength[i] = (i >= sof0_ && i <= sof15_) || (i >= app0_ && i <= (app0_ | 0x0F)) ||
(i == dht_ || i == dqt_ || i == dri_ || i == com_ || i == sos_);
// Container for the signature
bool bExtXMP = false;
@ -613,7 +614,8 @@ namespace Exiv2 {
// Read section marker
int marker = advanceToMarker();
if (marker < 0) throw Error(kerNotAJpeg);
if (marker < 0)
throw Error(kerNotAJpeg);
bool done = false;
bool first = true;
@ -630,10 +632,13 @@ namespace Exiv2 {
// Read size and signature
std::memset(buf.pData_, 0x0, buf.size_);
bufRead = io_->read(buf.pData_, bufMinSize);
if (io_->error()) throw Error(kerFailedToReadImageData);
if (bufRead < 2) throw Error(kerNotAJpeg);
if (io_->error())
throw Error(kerFailedToReadImageData);
if (bufRead < 2)
throw Error(kerNotAJpeg);
uint16_t size = mHasLength[marker] ? getUShort(buf.pData_, bigEndian) : 0;
if ( bPrint && mHasLength[marker] ) out << Internal::stringFormat(" | %7d ", size);
if (bPrint && mHasLength[marker])
out << Internal::stringFormat(" | %7d ", size);
// print signature for APPn
if (marker >= app0_ && marker <= (app0_ | 0x0F)) {
@ -663,7 +668,8 @@ namespace Exiv2 {
// and dumping the XMP in a post read operation similar to kpsIptcErase
// for the moment, dumping 'on the fly' is working fine
if (!bExtXMP) {
while (xmp[start]) start++;
while (xmp[start])
start++;
start++;
if (::strstr((char*)xmp + start, "HasExtendedXMP")) {
start = size; // ignore this packet, we'll get on the next time around
@ -746,11 +752,14 @@ namespace Exiv2 {
if (bFlir) {
// FLIRFILEHEAD* pFFF = (FLIRFILEHEAD*) (exif+start) ;
while (start < max) {
if ( exif[start] == 'I' && exif[start+1] == 'I' ) break;
if ( exif[start] == 'M' && exif[start+1] == 'M' ) break;
if (exif[start] == 'I' && exif[start + 1] == 'I')
break;
if (exif[start] == 'M' && exif[start + 1] == 'M')
break;
start++;
}
if ( start < max ) std::cout << " FFF start = " << start << std::endl ;
if (start < max)
std::cout << " FFF start = " << start << std::endl;
// << " index = " << pFFF->dwIndexOff << std::endl;
}
@ -759,7 +768,8 @@ namespace Exiv2 {
} else {
// create a copy on write memio object with the data, then print the structure
BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(exif + start, size - start));
if ( start < max ) printTiffStructure(*p,out,option,depth);
if (start < max)
printTiffStructure(*p, out, option, depth);
}
// restore and clean up
@ -777,17 +787,21 @@ namespace Exiv2 {
}
// Skip the segment if the size is known
if (io_->seek(size - bufRead, BasicIo::cur)) throw Error(kerFailedToReadImageData);
if (io_->seek(size - bufRead, BasicIo::cur))
throw Error(kerFailedToReadImageData);
if ( bLF ) out << std::endl;
if (bLF)
out << std::endl;
if (marker != sos_) {
// Read the beginning of the next segment
marker = advanceToMarker();
enforce(marker>=0, kerNoImageInInputData);
REPORT_MARKER;
}
done |= marker == eoi_ || marker == sos_;
if ( done && bPrint ) out << std::endl;
if (done && bPrint)
out << std::endl;
}
}
if (option == kpsIptcErase && iptcDataSegs.size()) {
@ -796,7 +810,10 @@ namespace Exiv2 {
uint32_t toggle = 0;
for (Uint32Vector_i i = iptcDataSegs.begin(); i != iptcDataSegs.end(); i++) {
std::cout << *i;
if ( toggle++ % 2 ) std::cout << std::endl; else std::cout << ' ' ;
if (toggle++ % 2)
std::cout << std::endl;
else
std::cout << ' ';
}
#endif
uint32_t count = (uint32_t)iptcDataSegs.size();
@ -814,7 +831,8 @@ namespace Exiv2 {
}
pos[count + 1] = io_->size() - pos[count];
#ifdef DEBUG
for ( uint64_t i = 0 ; i < count+2 ; i++ ) std::cout << pos[i] << " " ;
for (uint64_t i = 0; i < count + 2; i++)
std::cout << pos[i] << " ";
std::cout << std::endl;
#endif
// $ dd bs=1 skip=$((0)) count=$((13164)) if=ETH0138028.jpg of=E1.jpg
@ -828,7 +846,8 @@ namespace Exiv2 {
assert(tempIo.get() != 0);
for (uint64_t i = 0; i < (count / 2) + 1; i++) {
uint64_t start = pos[2 * i] + 2; // step JPG 2 byte marker
if ( start == 2 ) start = 0 ; // read the file 2 byte SOI
if (start == 2)
start = 0; // read the file 2 byte SOI
long length = (long)(pos[2 * i + 1] - start);
if (length) {
#ifdef DEBUG

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 B

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
import system_tests
class TestFirstPoC(system_tests.Case):
"""
Regression test for the first bug described in:
https://github.com/Exiv2/exiv2/issues/246
"""
url = "https://github.com/Exiv2/exiv2/issues/246"
filename = "{data_path}/1-string-format.jpg"
commands = ["{exiv2} -pS " + filename]
stdout = [
"""STRUCTURE OF JPEG FILE: """ + filename + """
address | marker | length | data
0 | 0xffd8 SOI
2 | 0xffe1 APP1 | 60 | Exif..II*.....0.i...........0000
"""]
stderr = ["""{exiv2_exception_message} """ + filename + """:
{kerNoImageInInputData}
"""]
retval = [1]

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
import system_tests
class TestFirstPoC(system_tests.Case):
"""
Regression test for the first bug described in:
https://github.com/Exiv2/exiv2/issues/253
"""
url = "https://github.com/Exiv2/exiv2/issues/253"
filename = "{data_path}/3-stringformat-outofbound-read"
commands = ["{exiv2} " + filename]
stdout = [""]
stderr = ["""{exiv2_exception_message} """ + filename + """:
{kerNotAJpeg}
"""]
retval = [1]

@ -19,6 +19,8 @@ kerFailedToReadImageData: Failed to read image data
kerCorruptedMetadata: corrupted image metadata
kerInvalidMalloc: invalid memory allocation request
kerInvalidTypeValue: invalid type value detected in Image::printIFDStructure
kerNotAJpeg : This does not look like a JPEG image
kerNoImageInInputData: Input data does not contain a valid image
addition_overflow_message: Overflow in addition
exiv2_exception_message: Exiv2 exception in print action for file
exiv2_overflow_exception_message: std::overflow_error exception in print action for file

Loading…
Cancel
Save