Skip to content

Commit 4274382

Browse files
committed
fix(softimage): validate channel packet metadata
Signed-off-by: Vlad (Kuzmin) Erium <libalias@gmail.com>
1 parent 6ea45b1 commit 4274382

4 files changed

Lines changed: 87 additions & 2 deletions

File tree

src/softimage.imageio/softimageinput.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ SoftimageInput::open(const std::string& name, ImageSpec& spec)
114114

115115
// Get the ChannelPackets
116116
ChannelPacket curPacket;
117+
int bits_per_channel = 0;
117118
std::vector<std::string> encodings;
118119
do {
119120
// Read the next packet into curPacket and store it off
@@ -129,13 +130,37 @@ SoftimageInput::open(const std::string& name, ImageSpec& spec)
129130
close();
130131
return false;
131132
}
133+
134+
if (bits_per_channel == 0) {
135+
bits_per_channel = curPacket.size;
136+
} else if (curPacket.size != bits_per_channel) {
137+
errorfmt("Inconsistent bits per channel {}", curPacket.size);
138+
close();
139+
return false;
140+
}
141+
142+
if ((curPacket.type & 0x3) > MIXED_RUN_LENGTH) {
143+
errorfmt("Unsupported channel encoding {}",
144+
static_cast<int>(curPacket.type));
145+
close();
146+
return false;
147+
}
148+
149+
if (curPacket.channelCode
150+
& ~(RED_CHANNEL | GREEN_CHANNEL | BLUE_CHANNEL | ALPHA_CHANNEL)) {
151+
errorfmt("Unsupported channel code 0x{:x}",
152+
static_cast<int>(curPacket.channelCode));
153+
close();
154+
return false;
155+
}
156+
132157
if (curPacket.channelCode == 0) {
133-
errorfmt("Channel packet with no channels");
158+
errorfmt("Channel packet has no channels");
134159
close();
135160
return false;
136161
}
137-
m_channel_packets.push_back(curPacket);
138162

163+
m_channel_packets.push_back(curPacket);
139164
encodings.push_back(encoding_name(m_channel_packets.back().type));
140165

141166
if (m_channel_packets.size() > 4) {

testsuite/softimage/ref/out.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,6 @@ src/broken01.pic : 16 x 4, 1 channel, uint8 softimage
4444
Stats FiniteCount: 64
4545
Constant: No
4646
Monochrome: Yes
47+
inconsistent-bpc-uncompressed-rejected
48+
inconsistent-bpc-pure-rle-rejected
49+
inconsistent-bpc-mixed-rle-rejected

testsuite/softimage/run.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,15 @@
1313
# Regression testing of error handling and corrupt files
1414
command += info_command ("--stats src/broken01.pic",
1515
info_program="iinfo", failureok=True)
16+
17+
command += run_app (pythonbin + " src/make-malformed-channel-pics.py",
18+
silent=True)
19+
malformed_channel_files = [
20+
"inconsistent-bpc-uncompressed.pic",
21+
"inconsistent-bpc-pure-rle.pic",
22+
"inconsistent-bpc-mixed-rle.pic",
23+
]
24+
for f in malformed_channel_files:
25+
command += run_app ("(" + oiio_app("iconvert") + f
26+
+ " out.null > /dev/null 2>&1 "
27+
+ "|| echo " + f.replace(".pic", "-rejected") + ")")
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright Contributors to the OpenImageIO project.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# https://github.com/AcademySoftwareFoundation/OpenImageIO
6+
7+
import struct
8+
9+
10+
MAGIC = 0x5380F634
11+
WIDTH = 2
12+
HEIGHT = 1
13+
RED_CHANNEL = 0x80
14+
GREEN_CHANNEL = 0x40
15+
16+
UNCOMPRESSED = 0
17+
PURE_RUN_LENGTH = 1
18+
MIXED_RUN_LENGTH = 2
19+
20+
21+
def header():
22+
comment = b"Malformed channel packet regression"
23+
return struct.pack(">If80s4sHHfHH", MAGIC, 1.0, comment, b"PICT",
24+
WIDTH, HEIGHT, 1.0, 0, 0)
25+
26+
27+
def channel_packet(chained, size, encoding, channel):
28+
return bytes((chained, size, encoding, channel))
29+
30+
31+
def write_pic(filename, encoding, red_payload, green_payload):
32+
with open(filename, "wb") as out:
33+
out.write(header())
34+
out.write(channel_packet(1, 16, encoding, RED_CHANNEL))
35+
out.write(channel_packet(0, 8, encoding, GREEN_CHANNEL))
36+
out.write(red_payload)
37+
out.write(green_payload)
38+
39+
40+
write_pic("inconsistent-bpc-uncompressed.pic", UNCOMPRESSED,
41+
b"\x00\x10\x00\x20", b"\x30\x40")
42+
write_pic("inconsistent-bpc-pure-rle.pic", PURE_RUN_LENGTH,
43+
b"\x02\x00\x10", b"\x02\x30")
44+
write_pic("inconsistent-bpc-mixed-rle.pic", MIXED_RUN_LENGTH,
45+
b"\x01\x00\x10\x00\x20", b"\x01\x30\x40")

0 commit comments

Comments
 (0)