Skip to content

Commit 047f6b7

Browse files
committed
Change logic to determine if segment has size
Note that the failing tests that had to be adapted were bad formed files from FUZZERs. We should not consider invalid markers like 0x00 or 0x52 but only undefined APPn markers.
1 parent 400632f commit 047f6b7

File tree

5 files changed

+29
-39
lines changed

5 files changed

+29
-39
lines changed

include/exiv2/jpgimage.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ class EXIV2API JpegBase : public Image {
150150
virtual int writeHeader(BasicIo& oIo) const = 0;
151151
//@}
152152

153-
154153
private:
155154
//! @name Manipulators
156155
//@{
@@ -246,7 +245,7 @@ class EXIV2API JpegImage : public JpegBase {
246245

247246
private:
248247
// Constant data
249-
static const byte blank_[]; ///< Minimal Jpeg image
248+
static const byte blank_[]; ///< Minimal Jpeg image
250249
};
251250

252251
//! Helper class to access %Exiv2 files

src/jpgimage.cpp

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,41 +29,30 @@
2929
namespace Exiv2 {
3030
namespace {
3131
// JPEG Segment markers (The first byte is always 0xFF, the value of these constants correspond to the 2nd byte)
32-
constexpr byte dht_ = 0xc4; //!< JPEG DHT marker: Define Huffman Table(s)
33-
constexpr byte dqt_ = 0xdb; //!< JPEG DQT marker: Define Quantization Table(s)
34-
constexpr byte dri_ = 0xdd; //!< JPEG DRI marker
3532
constexpr byte sos_ = 0xda; //!< JPEG SOS marker
36-
constexpr byte eoi_ = 0xd9; //!< JPEG EOI marker
3733
constexpr byte app0_ = 0xe0; //!< JPEG APP0 marker
3834
constexpr byte app1_ = 0xe1; //!< JPEG APP1 marker
3935
constexpr byte app2_ = 0xe2; //!< JPEG APP2 marker
4036
constexpr byte app13_ = 0xed; //!< JPEG APP13 marker
4137
constexpr byte com_ = 0xfe; //!< JPEG Comment marker
42-
constexpr byte soi_ = 0xd8; ///!< SOI marker
38+
39+
// Markers without payload
40+
constexpr byte soi_ = 0xd8; ///!< SOI marker
41+
constexpr byte eoi_ = 0xd9; //!< JPEG EOI marker
42+
constexpr byte rst1_ = 0xd0; //!< JPEG Restart 0 Marker (from 0xD0 to 0xD7 there might be 8 of these markers)
4343

4444
// Start of Frame markers, nondifferential Huffman-coding frames
4545
constexpr byte sof0_ = 0xc0; //!< JPEG Start-Of-Frame marker
46-
constexpr byte sof1_ = 0xc1; //!< JPEG Start-Of-Frame marker
47-
constexpr byte sof2_ = 0xc2; //!< JPEG Start-Of-Frame marker
4846
constexpr byte sof3_ = 0xc3; //!< JPEG Start-Of-Frame marker
4947

5048
// Start of Frame markers, differential Huffman-coding frames
5149
constexpr byte sof5_ = 0xc5; //!< JPEG Start-Of-Frame marker
52-
constexpr byte sof6_ = 0xc6; //!< JPEG Start-Of-Frame marker
53-
constexpr byte sof7_ = 0xc7; //!< JPEG Start-Of-Frame marker
54-
55-
// Start of Frame markers, nondifferential arithmetic-coding frames
56-
constexpr byte sof9_ = 0xc9; //!< JPEG Start-Of-Frame marker
57-
constexpr byte sof10_ = 0xca; //!< JPEG Start-Of-Frame marker
58-
constexpr byte sof11_ = 0xcb; //!< JPEG Start-Of-Frame marker
5950

6051
// Start of Frame markers, differential arithmetic-coding frames
61-
constexpr byte sof13_ = 0xcd; //!< JPEG Start-Of-Frame marker
62-
constexpr byte sof14_ = 0xce; //!< JPEG Start-Of-Frame marker
6352
constexpr byte sof15_ = 0xcf; //!< JPEG Start-Of-Frame marker
6453

65-
constexpr auto exifId_ = "Exif\0\0"; //!< Exif identifier
66-
constexpr auto jfifId_ = "JFIF\0"; //!< JFIF identifier
54+
constexpr auto exifId_ = "Exif\0\0"; //!< Exif identifier
55+
// constexpr auto jfifId_ = "JFIF\0"; //!< JFIF identifier
6756
constexpr auto xmpId_ = "http://ns.adobe.com/xap/1.0/\0"; //!< XMP packet identifier
6857
constexpr auto iccId_ = "ICC_PROFILE\0"; //!< ICC profile identifier
6958

@@ -76,12 +65,11 @@ inline bool inRange2(int value, int lo1, int hi1, int lo2, int hi2) {
7665
}
7766

7867
/// @brief has the segment a non-zero payload?
79-
/// @param marker The marker at the start of a segment
68+
/// @param m The marker at the start of a segment
8069
/// @return true if the segment has a length field/payload
81-
bool markerHasLength(byte marker) {
82-
/// \todo there are less markers without payload. Maybe we should revert the logic.
83-
return (marker >= sof0_ && marker <= sof15_) || (marker >= app0_ && marker <= (app0_ | 0x0F)) || marker == dht_ ||
84-
marker == dqt_ || marker == dri_ || marker == com_ || marker == sos_;
70+
bool markerHasLength(byte m) {
71+
bool markerWithoutLength = m >= rst1_ && m <= eoi_;
72+
return !markerWithoutLength;
8573
}
8674

8775
void readSegmentSize(const byte marker, BasicIo& io, std::array<byte, 2>& buf, std::uint16_t& size) {
@@ -294,6 +282,7 @@ byte JpegBase::advanceToMarker(ErrorCode err) const {
294282
throw Error(err);
295283
}
296284

285+
/// \todo should we check for validity of the marker? 0x59 does not look fine
297286
// Markers can start with any number of 0xff
298287
while ((c = io_->getb()) == 0xff) {
299288
}

tests/bugfixes/github/test_issue_1833.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ class TiffMnEntryDoCountInvalidTiffType(metaclass=CaseMeta):
1111

1212
filename = path("$data_path/issue_1833_poc.jpg")
1313
commands = ["$exiv2 -pS $filename"]
14-
stderr = [""]
15-
retval = [0]
14+
stderr = ["""$exiv2_exception_message """ + filename + """:
15+
$kerFailedToReadImageData
16+
"""]
17+
retval = [1]
1618

1719
compare_stdout = check_no_ASAN_UBSAN_errors

tests/bugfixes/github/test_issue_1881.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22

3-
from system_tests import CaseMeta, CopyTmpFiles, path
3+
from system_tests import CaseMeta, CopyTmpFiles, path, check_no_ASAN_UBSAN_errors
44
@CopyTmpFiles("$data_path/issue_1881_poc.jpg", "$data_path/issue_1881_coverage.jpg")
55

66
class SonyPreviewImageLargeAllocation(metaclass=CaseMeta):
@@ -13,6 +13,9 @@ class SonyPreviewImageLargeAllocation(metaclass=CaseMeta):
1313
filename1 = path("$tmp_path/issue_1881_poc.jpg")
1414
filename2 = path("$tmp_path/issue_1881_coverage.jpg")
1515
commands = ["$exiv2 -q -d I rm $filename1", "$exiv2 -q -d I rm $filename2"]
16-
stdout = ["",""]
17-
stderr = ["",""]
18-
retval = [0,0]
16+
stderr = ["""$exception_in_erase """ + filename1 + """:
17+
$kerFailedToReadImageData
18+
""", ""]
19+
retval = [1,0]
20+
21+
compare_stdout = check_no_ASAN_UBSAN_errors
Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import system_tests
22

3-
43
class BufferOverReadInNikon1MakerNotePrint0x0088(
54
metaclass=system_tests.CaseMeta):
65

@@ -9,12 +8,10 @@ class BufferOverReadInNikon1MakerNotePrint0x0088(
98
filename = system_tests.path(
109
"$data_path/NikonMakerNotePrint0x088_overread"
1110
)
12-
commands = ["$exiv2 -pt --grep AFFocusPos $filename"]
13-
stdout = [
14-
"""Exif.Nikon1.AFFocusPos Undefined 4 Invalid value; Center
15-
"""
16-
]
17-
stderr = [""]
18-
retval = [0]
11+
commands = ["$exiv2 -q -pt --grep AFFocusPos $filename"]
12+
stderr = ["""$exiv2_exception_message """ + filename + """:
13+
$kerFailedToReadImageData
14+
"""]
15+
retval = [1]
1916

2017
compare_stderr = system_tests.check_no_ASAN_UBSAN_errors

0 commit comments

Comments
 (0)