mirror of https://git.ffmpeg.org/ffmpeg.git
mjpegdec: consider chroma subsampling in size check
If the chroma components are subsampled, smaller buffers are allocated for them. In that case the maximal block_offset for the chroma components is not as large as for the luma component. This fixes out of bounds writes causing segmentation faults or memory corruption. Reviewed-by: Michael Niedermayer <michael@niedermayer.cc> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
This commit is contained in:
parent
a0a39acd01
commit
5adb5d9d89
|
@ -1246,7 +1246,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
|
||||||
int mb_bitmask_size,
|
int mb_bitmask_size,
|
||||||
const AVFrame *reference)
|
const AVFrame *reference)
|
||||||
{
|
{
|
||||||
int i, mb_x, mb_y;
|
int i, mb_x, mb_y, chroma_h_shift, chroma_v_shift, chroma_width, chroma_height;
|
||||||
uint8_t *data[MAX_COMPONENTS];
|
uint8_t *data[MAX_COMPONENTS];
|
||||||
const uint8_t *reference_data[MAX_COMPONENTS];
|
const uint8_t *reference_data[MAX_COMPONENTS];
|
||||||
int linesize[MAX_COMPONENTS];
|
int linesize[MAX_COMPONENTS];
|
||||||
|
@ -1263,6 +1263,11 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
|
||||||
|
|
||||||
s->restart_count = 0;
|
s->restart_count = 0;
|
||||||
|
|
||||||
|
av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, &chroma_h_shift,
|
||||||
|
&chroma_v_shift);
|
||||||
|
chroma_width = FF_CEIL_RSHIFT(s->width, chroma_h_shift);
|
||||||
|
chroma_height = FF_CEIL_RSHIFT(s->height, chroma_v_shift);
|
||||||
|
|
||||||
for (i = 0; i < nb_components; i++) {
|
for (i = 0; i < nb_components; i++) {
|
||||||
int c = s->comp_index[i];
|
int c = s->comp_index[i];
|
||||||
data[c] = s->picture_ptr->data[c];
|
data[c] = s->picture_ptr->data[c];
|
||||||
|
@ -1299,8 +1304,8 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
|
||||||
|
|
||||||
if (s->interlaced && s->bottom_field)
|
if (s->interlaced && s->bottom_field)
|
||||||
block_offset += linesize[c] >> 1;
|
block_offset += linesize[c] >> 1;
|
||||||
if ( 8*(h * mb_x + x) < s->width
|
if ( 8*(h * mb_x + x) < ((c == 1) || (c == 2) ? chroma_width : s->width)
|
||||||
&& 8*(v * mb_y + y) < s->height) {
|
&& 8*(v * mb_y + y) < ((c == 1) || (c == 2) ? chroma_height : s->height)) {
|
||||||
ptr = data[c] + block_offset;
|
ptr = data[c] + block_offset;
|
||||||
} else
|
} else
|
||||||
ptr = NULL;
|
ptr = NULL;
|
||||||
|
|
Loading…
Reference in New Issue