Skip to content

Commit 6ec094c

Browse files
authored
fix(softimage): More hardening against corrupted input files (#5155)
* Fix incorrect return check for fread in read_pixels_pure_run_length. * Detect and report error for unsupported packet type. * Fix possible infinite loop from malformed RLE packet with a zero run-count. * Check for valid y range in read_native_scanline. Signed-off-by: Larry Gritz <lg@larrygritz.com>
1 parent 2cdaedc commit 6ec094c

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

src/softimage.imageio/softimageinput.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ SoftimageInput::read_native_scanline(int subimage, int miplevel, int y,
175175
lock_guard lock(*this);
176176
if (!seek_subimage(subimage, miplevel))
177177
return false;
178+
if (y < 0 || y >= m_spec.height)
179+
return false;
178180

179181
bool result = false;
180182
if (y == (int)m_scanline_markers.size() - 1) {
@@ -271,9 +273,14 @@ SoftimageInput::read_next_scanline(void* data)
271273
ok = read_pixels_pure_run_length(cp, data);
272274
} else if (type == MIXED_RUN_LENGTH) {
273275
ok = read_pixels_mixed_run_length(cp, data);
276+
} else {
277+
errorfmt("Unsupported channel packet encoding {:d} in \"{}\"",
278+
int(cp.type), m_filename);
279+
close();
280+
return false;
274281
}
275282
if (!ok) {
276-
errorfmt("Failed to read channel packed type {:d} from \"{}\"",
283+
errorfmt("Failed to read channel packet type {:d} from \"{}\"",
277284
int(cp.type), m_filename);
278285
close();
279286
return false;
@@ -345,6 +352,12 @@ SoftimageInput::read_pixels_pure_run_length(
345352
if (fread(&curCount, 1, 1, m_fd) != 1)
346353
return false;
347354

355+
// Zero-length run is malformed
356+
if (curCount == 0) {
357+
errorfmt("Invalid RLE data");
358+
return false;
359+
}
360+
348361
// Clamp to avoid writing past the end of the scanline buffer
349362
if (linePixelCount + curCount > m_pic_header.width)
350363
curCount = m_pic_header.width - linePixelCount;
@@ -353,7 +366,7 @@ SoftimageInput::read_pixels_pure_run_length(
353366
// data pointer is set so we're supposed to write data there
354367
size_t pixelSize = pixelChannelSize * channels.size();
355368
uint8_t* pixelData = new uint8_t[pixelSize];
356-
if (fread(pixelData, pixelSize, 1, m_fd) != pixelSize)
369+
if (fread(pixelData, 1, pixelSize, m_fd) != pixelSize)
357370
return false;
358371

359372
// Now we've got the pixel value we need to push it into the data
@@ -472,6 +485,12 @@ SoftimageInput::read_pixels_mixed_run_length(
472485
longCount = curCount - 127;
473486
}
474487

488+
// Zero-length run is malformed
489+
if (longCount == 0) {
490+
errorfmt("Invalid RLE data");
491+
return false;
492+
}
493+
475494
// Clamp to avoid writing past the end of the scanline buffer
476495
if (linePixelCount + longCount > m_pic_header.width)
477496
longCount = m_pic_header.width - linePixelCount;

0 commit comments

Comments
 (0)