Skip to content

Commit e2bbc02

Browse files
committed
fix: broken pnm files with invalid resolution (#4561)
Fixes #4553 Caught during fuzzing with address sanitizer. The file appeared to have a resolution so big it would not be able to satisfy the memory allocation. Solution: add the check_open to take an early abort if resolutions are bigger than could possibly be valid. Also have Strutil::stoi hande 32 bit overflow without UB overflow that the sanitizer complains about (that was the other cascading error that this same test case encountered in the sanitizer after the bad allocation). Signed-off-by: Larry Gritz <[email protected]>
1 parent 17f4b42 commit e2bbc02

File tree

6 files changed

+20
-1
lines changed

6 files changed

+20
-1
lines changed

src/libutil/strutil.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1669,8 +1669,9 @@ Strutil::stoi(string_view str, size_t* pos, int base)
16691669
}
16701670
if (c >= base)
16711671
break;
1672-
acc = acc * base + c;
16731672
anydigits = true;
1673+
if (OIIO_LIKELY(!overflow))
1674+
acc = acc * base + c;
16741675
if (OIIO_UNLIKELY(acc > maxval))
16751676
overflow = true;
16761677
}

src/libutil/strutil_test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,7 @@ test_numeric_conversion()
891891
OIIO_CHECK_EQUAL(Strutil::stoi("-12345678901234567890"),
892892
std::numeric_limits<int>::min());
893893
OIIO_CHECK_EQUAL(Strutil::stoi("0x100", nullptr, 16), 256); // hex
894+
OIIO_CHECK_EQUAL(Strutil::stoi("25555555555555555551"), 2147483647);
894895

895896
OIIO_CHECK_EQUAL(Strutil::stoui("hi"), 0);
896897
OIIO_CHECK_EQUAL(Strutil::stoui(" "), 0);

src/pnm.imageio/pnminput.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,9 @@ PNMInput::open(const std::string& name, ImageSpec& newspec)
377377
if (!read_file_header())
378378
return false;
379379

380+
if (!check_open(m_spec)) // check for apparently invalid values
381+
return false;
382+
380383
newspec = m_spec;
381384
return true;
382385
}

testsuite/pnm/ref/out.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,6 @@ Reading ../oiio-images/pnm/test-3.pfm
6969
oiio:ColorSpace: "Rec709"
7070
pnm:bigendian: 1
7171
pnm:binary: 1
72+
oiiotool ERROR: read : "src/bad-4553.pgm": pnm image resolution may not exceed 65535x65535, but the file appears to be 2147483647x255. Possible corrupt input?
73+
Full command line was:
74+
> oiiotool --info -v -a --hash --oiioattrib try_all_readers 0 --printstats src/bad-4553.pgm

testsuite/pnm/run.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
# SPDX-License-Identifier: Apache-2.0
55
# https://github.com/AcademySoftwareFoundation/OpenImageIO
66

7+
redirect = ' >> out.txt 2>&1 '
8+
79
imagedir = OIIO_TESTSUITE_IMAGEDIR + "/pnm"
810

911
for f in [ "bw-ascii.pbm", "bw-binary.pbm",
@@ -16,3 +18,8 @@
1618
for f in files:
1719
command += info_command (imagedir + "/" + f,
1820
safematch=True, hash=True)
21+
22+
# Damaged files
23+
files = [ "src/bad-4553.pgm" ]
24+
for f in files:
25+
command += info_command (f, extraargs="--oiioattrib try_all_readers 0 --printstats", failureok=True)

testsuite/pnm/src/bad-4553.pgm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
P1
2+
25555555555555555551
3+
255
4+

0 commit comments

Comments
 (0)