diff --git a/crates/office2pdf/vendor/libeot/src/lzcomp/bitio.c b/crates/office2pdf/vendor/libeot/src/lzcomp/bitio.c --- a/crates/office2pdf/vendor/libeot/src/lzcomp/bitio.c +++ b/crates/office2pdf/vendor/libeot/src/lzcomp/bitio.c @@ -42,10 +42,16 @@ { /*assert( t->ReadOrWrite == 'r' ); */ if (t->input_bit_count-- == 0) { - t->input_bit_buffer = t->mem_bytes[t->mem_index++]; - if (t->mem_index > t->mem_size) { - longjmp(t->mem->env, ERR_BITIO_end_of_file); + /* The bounds test must precede the read. Upstream reads the byte first + * and then tests mem_index > mem_size, which lets one byte past the + * buffer reach the decoder, and then leaves through a jmp_buf that + * nothing fills. */ + if (t->mem_index >= t->mem_size) { + pdfpix_eot_fail(); + t->input_bit_count = 0; + return 0; } + t->input_bit_buffer = t->mem_bytes[t->mem_index++]; ++(t->bytes_in); t->input_bit_count = 7; } diff --git a/crates/office2pdf/vendor/libeot/src/lzcomp/lzcomp.c b/crates/office2pdf/vendor/libeot/src/lzcomp/lzcomp.c --- a/crates/office2pdf/vendor/libeot/src/lzcomp/lzcomp.c +++ b/crates/office2pdf/vendor/libeot/src/lzcomp/lzcomp.c @@ -929,8 +929,10 @@ } assert(pos == t->out_len); assert(t->usingRunLength || index == t->out_len); - if (pos != t->out_len) - longjmp(t->mem->env, ERR_LZCOMP_Decode_bounds); + if (pos != t->out_len) { + pdfpix_eot_fail(); + return NULL; /* unpackMtx turns this into EOT_MTX_ERROR */ + } *size = index; assert(dataOutSize >= *size); if (t->usingRunLength) { diff --git a/crates/office2pdf/vendor/libeot/src/lzcomp/liblzcomp.c b/crates/office2pdf/vendor/libeot/src/lzcomp/liblzcomp.c --- a/crates/office2pdf/vendor/libeot/src/lzcomp/liblzcomp.c +++ b/crates/office2pdf/vendor/libeot/src/lzcomp/liblzcomp.c @@ -49,6 +49,14 @@ sResult = BEReadU24(buf, &offsets[i]); CHK_CN(sResult, EOT_MTX_ERROR); } + /* The sizes below subtract unsigned offsets that the file controls. Out + * of order offsets wrap the difference to a huge length, and the bounds + * test that follows wraps with it. */ + if (offsets[1] < offsets[0] || offsets[2] < offsets[1] || + buf->size < offsets[2]) { + returnedStatus = EOT_MTX_ERROR; + goto CLEANUP; + } unsigned sizes[] = {offsets[1] - offsets[0], offsets[2] - offsets[1], buf->size - offsets[2]}; for (unsigned i = 0; i < 3; ++i) {