Skip to content

Commit 2e136a7

Browse files
committed
Re-fix buf img mode decompr err w/short prog JPEGs
This commit reverts 4dbc293 and 9f8f683 (the previous two commits) and fixes #613 the correct way. The crux of the issue wasn't the size of the whole_image virtual array but rather that, since last_iMCU_row is unsigned, (last_iMCU_row - 1) wrapped around to 0xFFFFFFFF when last_iMCU_row was 0. This caused the interblock smoothing algorithm introduced in 6d91e95 to erroneously try to access the next two iMCU rows, neither of which existed. The first attempt at a fix (4dbc293) exposed a NULL dereference, detected by OSS-Fuzz, that occurred when attempting to decompress a specially-crafted malformed JPEG image to a YUV buffer using tjDecompressToYUV*() with 1/4 IDCT scaling. Fixes #613 (again) Also fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49898
1 parent 9f8f683 commit 2e136a7

2 files changed

Lines changed: 10 additions & 12 deletions

File tree

ChangeLog.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ This allows both AltiVec-equipped (PowerPC G4 and G5) and non-AltiVec-equipped
1818
(PowerPC G3) CPUs to be supported using the same build of libjpeg-turbo.
1919

2020
4. Fixed an error ("Bogus virtual array access") that occurred when attempting
21-
to decompress a progressive JPEG image with a height less than or equal to
22-
(32 * the vertical sampling factor) using buffered image mode. This was a
23-
regression introduced by 2.1 beta1[6(b)].
21+
to decompress a progressive JPEG image with a height less than or equal to one
22+
iMCU (8 * the vertical sampling factor) using buffered-image mode with
23+
interblock smoothing enabled. This was a regression introduced by
24+
2.1 beta1[6(b)].
2425

2526

2627
2.1.3

jdcoefct.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
475475
if (!compptr->component_needed)
476476
continue;
477477
/* Count non-dummy DCT block rows in this iMCU row. */
478-
if (cinfo->output_iMCU_row < last_iMCU_row - 1) {
478+
if (cinfo->output_iMCU_row + 1 < last_iMCU_row) {
479479
block_rows = compptr->v_samp_factor;
480480
access_rows = block_rows * 3; /* this and next two iMCU rows */
481481
} else if (cinfo->output_iMCU_row < last_iMCU_row) {
@@ -560,7 +560,7 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
560560
next_block_row = buffer_ptr;
561561

562562
if (block_row < block_rows - 2 ||
563-
cinfo->output_iMCU_row < last_iMCU_row - 1)
563+
cinfo->output_iMCU_row + 1 < last_iMCU_row)
564564
next_next_block_row =
565565
buffer[block_row + 2] + cinfo->master->first_MCU_col[ci];
566566
else
@@ -835,21 +835,18 @@ jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
835835

836836
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
837837
ci++, compptr++) {
838-
JDIMENSION num_rows =
839-
(JDIMENSION)jround_up((long)compptr->height_in_blocks,
840-
(long)compptr->v_samp_factor);
841838
access_rows = compptr->v_samp_factor;
842839
#ifdef BLOCK_SMOOTHING_SUPPORTED
843840
/* If block smoothing could be used, need a bigger window */
844-
if (cinfo->progressive_mode) {
841+
if (cinfo->progressive_mode)
845842
access_rows *= 5;
846-
num_rows = MAX(num_rows, (JDIMENSION)access_rows);
847-
}
848843
#endif
849844
coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
850845
((j_common_ptr)cinfo, JPOOL_IMAGE, TRUE,
851846
(JDIMENSION)jround_up((long)compptr->width_in_blocks,
852-
(long)compptr->h_samp_factor), num_rows,
847+
(long)compptr->h_samp_factor),
848+
(JDIMENSION)jround_up((long)compptr->height_in_blocks,
849+
(long)compptr->v_samp_factor),
853850
(JDIMENSION)access_rows);
854851
}
855852
coef->pub.consume_data = consume_data;

0 commit comments

Comments
 (0)