Skip to content

Commit c2b1826

Browse files
committed
Harden IDManifest parsing against illegal shift and string prefix OOB
`readVariableLengthInteger()` must not apply `(byte & 127) << shift` when `shift >= 64`; that is undefined behavior for `uint64_t` and could yield corrupted lengths for string list parsing. Reject encodings that exceed representable shifts. When decoding compressed string lists, the common-prefix length is encoded with one or two leading bytes depending on whether the previous string exceeded 255 characters. Require each string to be at least that many bytes before reading those prefix bytes, avoiding out-of-bounds indexing on undersized entries. Made with Cursor Signed-off-by: Cary Phillips <cary@ilm.com>
1 parent 1bd1988 commit c2b1826

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

src/lib/OpenEXR/ImfIDManifest.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ readVariableLengthInteger (const char*& readPtr, const char* endPtr)
115115
throw IEX_NAMESPACE::InputExc (
116116
"IDManifest too small for variable length integer");
117117
}
118+
// Each chunk contributes at most 7 bits; shifts must stay < 64 or
119+
// (byte & 127) << shift has undefined behavior (C++).
120+
if (shift >= 64)
121+
{
122+
throw IEX_NAMESPACE::InputExc (
123+
"Invalid variable-length integer in IDManifest");
124+
}
118125
byte = *(unsigned char*) readPtr++;
119126
// top bit of byte isn't part of actual number, it just indicates there's more info to come
120127
// so take bottom 7 bits, shift them to the right place, and insert them
@@ -337,6 +344,13 @@ IDManifest::init (const char* data, const char* endOfData)
337344
//
338345
// previous string had more than 255 characters?
339346
//
347+
const size_t minPrefixLen =
348+
stringList[i - 1].size () > 255 ? size_t (2) : size_t (1);
349+
if (stringList[i].size () < minPrefixLen)
350+
{
351+
throw IEX_NAMESPACE::InputExc (
352+
"IDManifest string too small for common prefix length");
353+
}
340354
if (stringList[i - 1].size () > 255)
341355
{
342356
common = size_t (((unsigned char) (stringList[i][0])) << 8) +

0 commit comments

Comments
 (0)