Skip to content

Commit a505d6f

Browse files
committed
More unit tests for Photoshop methods
1 parent 8ab7800 commit a505d6f

File tree

2 files changed

+151
-10
lines changed

2 files changed

+151
-10
lines changed

src/jpgimage.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ int Photoshop::locateIrb(const byte* pPsData, size_t sizePsData, uint16_t psTag,
7171
std::cerr << "Photoshop::locateIrb: ";
7272
#endif
7373
// Data should follow Photoshop format, if not exit
74-
while (position <= sizePsData - 12 && isIrb(pPsData + position)) {
74+
while (position <= (sizePsData - 12) && isIrb(pPsData + position)) {
7575
const byte* hrd = pPsData + position;
7676
position += 4;
7777
uint16_t type = getUShort(pPsData + position, bigEndian);
@@ -152,16 +152,17 @@ DataBuf Photoshop::setIptcIrb(const byte* pPsData, size_t sizePsData, const Iptc
152152
uint32_t sizeIptc = 0;
153153
uint32_t sizeHdr = 0;
154154
DataBuf rc;
155-
// Safe to call with zero psData.size_
156155
if (0 > Photoshop::locateIptcIrb(pPsData, sizePsData, &record, &sizeHdr, &sizeIptc)) {
157156
return rc;
158157
}
158+
159159
Blob psBlob;
160160
const auto sizeFront = static_cast<size_t>(record - pPsData);
161161
// Write data before old record.
162162
if (sizePsData > 0 && sizeFront > 0) {
163163
append(psBlob, pPsData, sizeFront);
164164
}
165+
165166
// Write new iptc record if we have it
166167
DataBuf rawIptc = IptcParser::encode(iptcData);
167168
if (!rawIptc.empty()) {
@@ -177,8 +178,8 @@ DataBuf Photoshop::setIptcIrb(const byte* pPsData, size_t sizePsData, const Iptc
177178
if (rawIptc.size() & 1)
178179
psBlob.push_back(0x00);
179180
}
180-
// Write existing stuff after record,
181-
// skip the current and all remaining IPTC blocks
181+
182+
// Write existing stuff after record, skip the current and all remaining IPTC blocks
182183
size_t pos = sizeFront;
183184
long nextSizeData = Safe::add<long>(static_cast<long>(sizePsData), -static_cast<long>(pos));
184185
enforce(nextSizeData >= 0, ErrorCode::kerCorruptedMetadata);

unitTests/test_Photoshop.cpp

Lines changed: 146 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ TEST(Photoshop_isIrb, returnsTrueWithValidMarkers) {
1616
}
1717
}
1818

19-
2019
TEST(Photoshop_isIrb, returnsFalseWithInvalidMarkers) {
21-
ASSERT_FALSE(Photoshop::isIrb(reinterpret_cast<const byte *>("7BIM")));
22-
ASSERT_FALSE(Photoshop::isIrb(reinterpret_cast<const byte *>("AGHg")));
23-
ASSERT_FALSE(Photoshop::isIrb(reinterpret_cast<const byte *>("dcsr")));
24-
ASSERT_FALSE(Photoshop::isIrb(reinterpret_cast<const byte *>("LUIS")));
20+
ASSERT_FALSE(Photoshop::isIrb(reinterpret_cast<const byte*>("7BIM")));
21+
ASSERT_FALSE(Photoshop::isIrb(reinterpret_cast<const byte*>("AGHg")));
22+
ASSERT_FALSE(Photoshop::isIrb(reinterpret_cast<const byte*>("dcsr")));
23+
ASSERT_FALSE(Photoshop::isIrb(reinterpret_cast<const byte*>("LUIS")));
2524
}
2625

2726
TEST(Photoshop_isIrb, returnsFalseWithNullPointer) {
@@ -30,5 +29,146 @@ TEST(Photoshop_isIrb, returnsFalseWithNullPointer) {
3029

3130
/// \note probably this is not safe and we need to remove it
3231
TEST(Photoshop_isIrb, returnsFalseWithShorterMarker) {
33-
ASSERT_FALSE(Photoshop::isIrb(reinterpret_cast<const byte *>("8BI")));
32+
ASSERT_FALSE(Photoshop::isIrb(reinterpret_cast<const byte*>("8BI")));
33+
}
34+
35+
TEST(Photoshop_locateIrb, returnsMinus2withInvalidPhotoshopIRB) {
36+
const std::string data{"8BIMlalalalalalala"};
37+
const Exiv2::byte* record;
38+
uint32_t sizeHdr = 0;
39+
uint32_t sizeData = 0;
40+
ASSERT_EQ(-2, Photoshop::locateIrb(reinterpret_cast<const byte*>(data.c_str()), data.size(), Photoshop::iptc_,
41+
&record, &sizeHdr, &sizeData));
42+
}
43+
44+
TEST(Photoshop_locateIrb, returnsMinus2WithMarkerNotStartingWith8BIM) {
45+
const std::string data{"7BIMlalalalalalalala"};
46+
const Exiv2::byte* record;
47+
uint32_t sizeHdr = 0;
48+
uint32_t sizeData = 0;
49+
ASSERT_EQ(-2, Photoshop::locateIrb(reinterpret_cast<const byte*>(data.c_str()), data.size(), Photoshop::iptc_,
50+
&record, &sizeHdr, &sizeData));
51+
}
52+
53+
TEST(Photoshop_locateIrb, returns3withNotLongEnoughData) {
54+
const std::string data{"8BIMlala"};
55+
const Exiv2::byte* record;
56+
uint32_t sizeHdr = 0;
57+
uint32_t sizeData = 0;
58+
ASSERT_EQ(3, Photoshop::locateIrb(reinterpret_cast<const byte*>(data.c_str()), data.size(), Photoshop::iptc_, &record,
59+
&sizeHdr, &sizeData));
60+
}
61+
62+
TEST(Photoshop_locateIrb, returns0withGoodIptcIrb) {
63+
// Data taken from file test/data/DSC_3079.jpg
64+
// The IPTC marker is 0x04 0x04
65+
const std::array<byte, 68> data{0x38, 0x42, 0x49, 0x4d, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x01,
66+
0x5a, 0x00, 0x03, 0x1b, 0x25, 0x47, 0x1c, 0x02, 0x00, 0x00, 0x02, 0x00, 0x04, 0x1c,
67+
0x02, 0x19, 0x00, 0x07, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x00, 0x38, 0x42,
68+
0x49, 0x4d, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x65, 0x16, 0xda,
69+
0x51, 0x3f, 0xfe, 0x5c, 0xbb, 0x52, 0xf3, 0x2e, 0x36, 0x7b, 0x97, 0x3d};
70+
71+
const Exiv2::byte* record;
72+
uint32_t sizeHdr = 0;
73+
uint32_t sizeData = 0;
74+
75+
ASSERT_EQ(0, Photoshop::locateIrb(data.data(), data.size(), Photoshop::iptc_, &record, &sizeHdr, &sizeData));
76+
ASSERT_EQ(12, sizeHdr);
77+
ASSERT_EQ(27, sizeData);
78+
}
79+
80+
TEST(Photoshop_locateIptcIrb, returns0withGoodIptcIrb) {
81+
// Data taken from file test/data/DSC_3079.jpg
82+
// The IPTC marker is 0x04 0x04
83+
const std::array<byte, 68> data{0x38, 0x42, 0x49, 0x4d, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x01,
84+
0x5a, 0x00, 0x03, 0x1b, 0x25, 0x47, 0x1c, 0x02, 0x00, 0x00, 0x02, 0x00, 0x04, 0x1c,
85+
0x02, 0x19, 0x00, 0x07, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x00, 0x38, 0x42,
86+
0x49, 0x4d, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x65, 0x16, 0xda,
87+
0x51, 0x3f, 0xfe, 0x5c, 0xbb, 0x52, 0xf3, 0x2e, 0x36, 0x7b, 0x97, 0x3d};
88+
89+
const Exiv2::byte* record;
90+
uint32_t sizeHdr = 0;
91+
uint32_t sizeData = 0;
92+
93+
ASSERT_EQ(0, Photoshop::locateIptcIrb(data.data(), data.size(), &record, &sizeHdr, &sizeData));
94+
ASSERT_EQ(12, sizeHdr);
95+
ASSERT_EQ(27, sizeData);
96+
}
97+
98+
TEST(Photoshop_locateIptcIrb, returns3withoutIptcMarker) {
99+
// Data taken from file test/data/DSC_3079.jpg
100+
// The IPTC marker (0x04 0x04) was manipulated to 0x03 0x04
101+
const std::array<byte, 68> data{0x38, 0x42, 0x49, 0x4d, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x01,
102+
0x5a, 0x00, 0x03, 0x1b, 0x25, 0x47, 0x1c, 0x02, 0x00, 0x00, 0x02, 0x00, 0x04, 0x1c,
103+
0x02, 0x19, 0x00, 0x07, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x00, 0x38, 0x42,
104+
0x49, 0x4d, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x65, 0x16, 0xda,
105+
0x51, 0x3f, 0xfe, 0x5c, 0xbb, 0x52, 0xf3, 0x2e, 0x36, 0x7b, 0x97, 0x3d};
106+
107+
const Exiv2::byte* record;
108+
uint32_t sizeHdr = 0;
109+
uint32_t sizeData = 0;
110+
111+
ASSERT_EQ(3, Photoshop::locateIptcIrb(data.data(), data.size(), &record, &sizeHdr, &sizeData));
112+
}
113+
114+
TEST(Photoshop_locatePreviewIrb, returns0withGoodPreviewIrb) {
115+
// Data taken from file test/data/DSC_3079.jpg
116+
// The IPTC marker is 0x04 0x04 was transformed to a Preview one => (0x04 0x0c)
117+
const std::array<byte, 68> data{0x38, 0x42, 0x49, 0x4d, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x01,
118+
0x5a, 0x00, 0x03, 0x1b, 0x25, 0x47, 0x1c, 0x02, 0x00, 0x00, 0x02, 0x00, 0x04, 0x1c,
119+
0x02, 0x19, 0x00, 0x07, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x00, 0x38, 0x42,
120+
0x49, 0x4d, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x65, 0x16, 0xda,
121+
0x51, 0x3f, 0xfe, 0x5c, 0xbb, 0x52, 0xf3, 0x2e, 0x36, 0x7b, 0x97, 0x3d};
122+
123+
const Exiv2::byte* record;
124+
uint32_t sizeHdr = 0;
125+
uint32_t sizeData = 0;
126+
127+
ASSERT_EQ(0, Photoshop::locatePreviewIrb(data.data(), data.size(), &record, &sizeHdr, &sizeData));
128+
ASSERT_EQ(12, sizeHdr);
129+
ASSERT_EQ(27, sizeData);
130+
}
131+
132+
// --------------------------------
133+
134+
TEST(Photoshop_setIptcIrb, withEmptyDataReturnsEmptyBuffer) {
135+
const IptcData iptc;
136+
DataBuf buf = Photoshop::setIptcIrb(nullptr, 0, iptc);
137+
ASSERT_TRUE(buf.empty());
138+
}
139+
140+
TEST(Photoshop_setIptcIrb, detectIntegerOverflow_withDataFromPOC2179) {
141+
const std::array<byte, 141> data{
142+
0x38, 0x42, 0x49, 0x4d, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x04,
143+
0x00, 0x20, 0x00, 0x00, 0x00, 0x75, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20,
144+
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xff, 0x20, 0x20, 0x20,
145+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd9, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
146+
0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
147+
0xff, 0xff, 0x20, 0x20, 0xff, 0x20, 0xff, 0xff, 0xff, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
148+
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xff, 0x20, 0x20, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
149+
0xff, 0xff, 0xff, 0x20, 0xff, 0xff, 0xff, 0xff, 0x20, 0xff, 0xff, 0x20, 0xff, 0xff, 0xff};
150+
151+
const IptcData iptc;
152+
153+
ASSERT_THROW(Photoshop::setIptcIrb(data.data(), data.size(), iptc), Exiv2::Error);
154+
}
155+
156+
TEST(Photoshop_setIptcIrb, returnsEmptyBufferWhenDataDoesNotHave8BIM) {
157+
// First byte replaced from 0x38 to 0x37
158+
const std::array<byte, 181> data{
159+
0x37, 0x42, 0x49, 0x4d, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4d, 0x04, 0x04, 0x00,
160+
0x20, 0x00, 0x00, 0x00, 0x75, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20,
161+
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xff, 0x20, 0x20, 0x20, 0xff, 0xff, 0xff,
162+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd9, 0x20, 0xff, 0x20, 0x20, 0xff, 0xed, 0x00, 0x15, 0x50, 0x68, 0x6f, 0x74,
163+
0x6f, 0x73, 0x68, 0x6f, 0x70, 0x20, 0x33, 0x2e, 0x30, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xed, 0x00, 0x54,
164+
0x50, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x20, 0x33, 0x2e, 0x30, 0x00, 0x20, 0x20, 0x20, 0x20, 0xff,
165+
0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xff, 0x20, 0x20, 0xff, 0x20, 0xff,
166+
0xff, 0xff, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff,
167+
0xff, 0x20, 0x20, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0xff, 0xff, 0xff, 0xff, 0x20,
168+
0xff, 0xff, 0x20, 0xff, 0xff, 0xff, 0xff, 0xd9, 0x0d, 0x0a};
169+
170+
const IptcData iptc;
171+
172+
DataBuf buf = Photoshop::setIptcIrb(data.data(), data.size(), iptc);
173+
ASSERT_TRUE(buf.empty());
34174
}

0 commit comments

Comments
 (0)