Hello, attached patches fix several instances of undefined behaviour encountered when running the FATE suite.
- Andreas
>From 95ab387c56fd9a2e4b2fb26d164fff93848d5947 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 06:03:49 +0100 Subject: [PATCH 01/17] avcodec/dcaenc: Fix undefined left shift of negative numbers Affected the acodec-dca and acodec-dca2 FATE tests. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavcodec/dcaenc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c index a40d2e0ca0..87fb5f5457 100644 --- a/libavcodec/dcaenc.c +++ b/libavcodec/dcaenc.c @@ -925,10 +925,10 @@ static void fill_in_adpcm_bufer(DCAEncContext *c) * But there are no proper value in decoder history, so likely result will be no good. * Bitstream has "Predictor history flag switch", but this flag disables history for all subbands */ - samples[0] = c->adpcm_history[ch][band][0] << 7; - samples[1] = c->adpcm_history[ch][band][1] << 7; - samples[2] = c->adpcm_history[ch][band][2] << 7; - samples[3] = c->adpcm_history[ch][band][3] << 7; + samples[0] = c->adpcm_history[ch][band][0] * (1 << 7); + samples[1] = c->adpcm_history[ch][band][1] * (1 << 7); + samples[2] = c->adpcm_history[ch][band][2] * (1 << 7); + samples[3] = c->adpcm_history[ch][band][3] * (1 << 7); } } } -- 2.27.0
>From 1d1063a06b6e2f84e6e3030d7a2526a312842bf0 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 06:22:24 +0100 Subject: [PATCH 02/17] avfilter/af_hdcd: Fix undefined shifts Affected the filter-hdcd-* FATE tests. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavfilter/af_hdcd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index 251d03229a..978f63599b 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -1053,7 +1053,7 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state *states, int channels, in for (j = result - 1; j >= 0; j--) { for (i = 0; i < channels; i++) - bits[i] |= (*(samples++) & 1) << j; + bits[i] |= (*(samples++) & 1U) << j; samples += stride - channels; } @@ -1210,7 +1210,7 @@ static int hdcd_analyze(int32_t *samples, int count, int stride, int gain, int t int32_t *samples_end = samples + stride * count; for (i = 0; i < count; i++) { - samples[i * stride] <<= 15; + samples[i * stride] *= 1 << 15; if (mode == HDCD_ANA_PE) { int pel = (samples[i * stride] >> 16) & 1; int32_t sample = samples[i * stride]; @@ -1284,13 +1284,13 @@ static int hdcd_envelope(int32_t *samples, int count, int stride, int vbits, int av_assert0(asample <= max_asample); sample = sample >= 0 ? peaktab[asample] : -peaktab[asample]; } else - sample <<= shft; + sample *= (1 << shft); samples[i * stride] = sample; } } else { for (i = 0; i < count; i++) - samples[i * stride] <<= shft; + samples[i * stride] *= (1 << shft); } if (gain <= target_gain) { -- 2.27.0
>From e6ed3b819a09070e90d3401ba6d784f15b2ee485 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 07:15:56 +0100 Subject: [PATCH 03/17] avcodec/mpegvideo_enc: Don't apply non-zero offset to null pointer Affected many FATE tests (mostly vsynth ones). Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavcodec/mpegvideo_enc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 7eecfce27c..a095062052 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -1696,7 +1696,8 @@ no_output_pic: // input is not a shared pix -> reuse buffer for current_pix s->current_picture_ptr = s->reordered_input_picture[0]; for (i = 0; i < 4; i++) { - s->new_picture.f->data[i] += INPLACE_OFFSET; + if (s->new_picture.f->data[i]) + s->new_picture.f->data[i] += INPLACE_OFFSET; } } ff_mpeg_unref_picture(s->avctx, &s->current_picture); -- 2.27.0
>From 1a88537b26c44a81e7eb6cccb543d4ad70295e47 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <mich...@niedermayer.cc> Date: Mon, 15 Mar 2021 09:47:43 +0100 Subject: [PATCH 04/17] avutil/common: Add FF_PTR_ADD() Suggested-by: Andreas Rheinhardt Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> --- I included this as several of the latter patches need it. This does not mean that I like this macro being public. libavutil/common.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavutil/common.h b/libavutil/common.h index aee353d399..c2d47a45b4 100644 --- a/libavutil/common.h +++ b/libavutil/common.h @@ -108,6 +108,8 @@ #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) +#define FF_PTR_ADD(ptr, off) ((off) ? (ptr) + (off) : (ptr)) + /* misc math functions */ #ifdef HAVE_AV_CONFIG_H -- 2.27.0
>From 4eef11f15b2b852a01e2a3e8bbf2c7d49a0e5771 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 09:21:22 +0100 Subject: [PATCH 05/17] avcodec/proresdec2: Don't apply non-zero offset to null pointer Affected ProRes without alpha; affected 32 FATE tests, e.g. prores-422, prores-422_proxy, prores-422_lt or matroska-prores-header-insertion-bz2. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- Is it actually guaranteed that the Y and A linesizes (and U and V linesizes) coincide (the code relies it both before and after this patch)? libavcodec/proresdec2.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index 136f341c08..5a01c89c48 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -623,8 +623,8 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int AVFrame *pic = ctx->frame; int i, hdr_size, qscale, log2_chroma_blocks_per_mb; int luma_stride, chroma_stride; - int y_data_size, u_data_size, v_data_size, a_data_size; - uint8_t *dest_y, *dest_u, *dest_v, *dest_a; + int y_data_size, u_data_size, v_data_size, a_data_size, offset; + uint8_t *dest_y, *dest_u, *dest_v; LOCAL_ALIGNED_16(int16_t, qmat_luma_scaled, [64]); LOCAL_ALIGNED_16(int16_t, qmat_chroma_scaled,[64]); int mb_x_shift; @@ -676,16 +676,16 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int log2_chroma_blocks_per_mb = 1; } - dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); + offset = (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); + dest_y = pic->data[0] + offset; dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); - dest_a = pic->data[3] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) { dest_y += pic->linesize[0]; dest_u += pic->linesize[1]; dest_v += pic->linesize[2]; - dest_a += pic->linesize[3]; + offset += pic->linesize[3]; } ret = decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride, @@ -722,10 +722,12 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int } /* decode alpha plane if available */ - if (ctx->alpha_info && pic->data[3] && a_data_size) + if (ctx->alpha_info && pic->data[3] && a_data_size) { + uint8_t *dest_a = pic->data[3] + offset; decode_slice_alpha(ctx, (uint16_t*)dest_a, luma_stride, buf + y_data_size + u_data_size + v_data_size, a_data_size, slice->mb_count); + } slice->ret = 0; return 0; -- 2.27.0
>From e61d4be3acae6f54df3126134c1297f368a35de2 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 09:43:22 +0100 Subject: [PATCH 06/17] libswresample/audioconvert: Fix undefined NULL + 0 Affected 26 FATE tests like swr-resample_async-s16p-44100-8000. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- This is an instance where a compiler could use UB to optimize the check away. libswresample/audioconvert.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libswresample/audioconvert.c b/libswresample/audioconvert.c index 89ee7bfae3..500aa0e5c5 100644 --- a/libswresample/audioconvert.c +++ b/libswresample/audioconvert.c @@ -237,10 +237,10 @@ int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len const int ich= ctx->ch_map ? ctx->ch_map[ch] : ch; const int is= ich < 0 ? 0 : (in->planar ? 1 : in->ch_count) * in->bps; const uint8_t *pi= ich < 0 ? ctx->silence : in->ch[ich]; - uint8_t *po= out->ch[ch]; - uint8_t *end= po + os*len; + uint8_t *end, *po = out->ch[ch]; if(!po) continue; + end = po + os * len; ctx->conv_f(po+off*os, pi+off*is, is, os, end); } return 0; -- 2.27.0
>From 18c9f24244decbe24cacf23193da08ebefb9ddb3 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 12:42:21 +0100 Subject: [PATCH 07/17] avcodec/qtrleenc: Use keyframe when no previous frame is available If keeping a reference to an earlier frame failed, the next frame must be an I frame for lack of reference frame. This commit implements this. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavcodec/qtrleenc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c index 8b0edf7b3d..0f5bedcdcd 100644 --- a/libavcodec/qtrleenc.c +++ b/libavcodec/qtrleenc.c @@ -369,7 +369,8 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size, 0)) < 0) return ret; - if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) { + if (avctx->gop_size == 0 || !s->previous_frame->data[0] || + (s->avctx->frame_number % avctx->gop_size) == 0) { /* I-Frame */ s->key_frame = 1; } else { -- 2.27.0
>From 676fe22b1e6a976dd041b38c8471763374e5b805 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 13:37:43 +0100 Subject: [PATCH 08/17] avcodec/qtrleenc: Fix negative linesizes, don't use NULL + offset Before commit f1e17eb446577180ee9976730aacb46563766518, the qtrle encoder had undefined pointer arithmetic: Outside of a loop, two pointers were set to point to the ith element (with index i-1) of a line of a frame. At the end of each loop iteration, these pointers were decremented, so that they pointed to the -1th element of the line after the loop. Furthermore, one of these pointers can be NULL (in which case all pointer arithmetic is automatically undefined behaviour). Commit f1e17eb44 added a check in order to ensure that the elements never point to the -1th element of the array: The pointers are only decremented if they are bigger than the frame's base pointer (i.e. AVFrame.data[0]). Yet this check does not work at all in case of negative linesizes; furthermore in case the pointer that can be NULL is NULL initializing it still involves undefined pointer arithmetic. This commit fixes both these issues: First, non-NULL pointers are initialized to point to the element after the ith element and decrementing is moved to the beginning of the loop. Second, if a pointer is NULL, it is just made to point to the other pointer, as this allows to avoid checks before decrementing it. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavcodec/qtrleenc.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c index 0f5bedcdcd..f7eee4a591 100644 --- a/libavcodec/qtrleenc.c +++ b/libavcodec/qtrleenc.c @@ -155,10 +155,14 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui int sec_lowest_bulk_cost; int sec_lowest_bulk_cost_index; - uint8_t *this_line = p-> data[0] + line*p-> linesize[0] + - (width - 1)*s->pixel_size; - uint8_t *prev_line = s->previous_frame->data[0] + line * s->previous_frame->linesize[0] + - (width - 1)*s->pixel_size; + const uint8_t *this_line = p->data[0] + line * p->linesize[0] + width * s->pixel_size; + /* There might be no earlier frame if the current frame is a keyframe. + * So just use a pointer to the current frame to avoid a check + * to avoid NULL - s->pixel_size (which is undefined behaviour). */ + const uint8_t *prev_line = s->key_frame ? this_line + : s->previous_frame->data[0] + + line * s->previous_frame->linesize[0] + + width * s->pixel_size; s->length_table[width] = 0; skipcount = 0; @@ -175,6 +179,9 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui int prev_bulk_cost; + this_line -= s->pixel_size; + prev_line -= s->pixel_size; + /* If our lowest bulk cost index is too far away, replace it * with the next lowest bulk cost */ if (FFMIN(width, i + MAX_RLE_BULK) < lowest_bulk_cost_index) { @@ -259,10 +266,6 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui /* These bulk costs increase every iteration */ lowest_bulk_cost += s->pixel_size; sec_lowest_bulk_cost += s->pixel_size; - if (this_line >= p->data[0] + s->pixel_size) - this_line -= s->pixel_size; - if (prev_line >= s->previous_frame->data[0] + s->pixel_size) - prev_line -= s->pixel_size; } /* Good! Now we have the best sequence for this line, let's output it. */ -- 2.27.0
>From 4f49c6a8ff5f767f35de661b25058dcebbddb46e Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 14:11:18 +0100 Subject: [PATCH 09/17] avcodec/lcldec: Fix undefined NULL + 0 Affected the FATE tests vsynth*-zlib, mszh and zlib. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- The offset variable has been added because GCC otherwise complains about using * instead of &&. libavcodec/lcldec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 2dcd249b65..d281733fdd 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -173,7 +173,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac int uqvq, ret; unsigned int mthread_inlen, mthread_outlen; unsigned int len = buf_size; - int linesize; + int linesize, offset; if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) return ret; @@ -373,8 +373,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac /* Convert colorspace */ y_out = frame->data[0] + (height - 1) * frame->linesize[0]; - u_out = frame->data[1] + (height - 1) * frame->linesize[1]; - v_out = frame->data[2] + (height - 1) * frame->linesize[2]; + offset = (height - 1) * frame->linesize[1]; + u_out = FF_PTR_ADD(frame->data[1], offset); + offset = (height - 1) * frame->linesize[2]; + v_out = FF_PTR_ADD(frame->data[2], offset); switch (c->imgtype) { case IMGTYPE_YUV111: for (row = 0; row < height; row++) { -- 2.27.0
>From a5095b86d3644f99652e892f34ddfc499644991c Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 14:40:40 +0100 Subject: [PATCH 10/17] avcodec/mss12: Don't apply non-zero offset to null pointer Affected the FATE tests mss2-wmv and mss1-pal. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavcodec/mss12.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libavcodec/mss12.c b/libavcodec/mss12.c index 5a5bd9a91b..5afdaacfe6 100644 --- a/libavcodec/mss12.c +++ b/libavcodec/mss12.c @@ -291,14 +291,15 @@ static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx, return decode_pixel(acoder, pctx, ref_pix, nlen, 1); } -static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic, +static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_dst, int x, int y, int width, int height, ptrdiff_t stride, ptrdiff_t rgb_stride, PixContext *pctx, const uint32_t *pal) { int i, j, p; - uint8_t *rgb_dst = rgb_pic + x * 3 + y * rgb_stride; + rgb_stride = rgb_dst ? rgb_stride : 0; + rgb_dst = rgb_dst ? rgb_dst + x * 3 + y * rgb_stride : NULL; dst += x + y * stride; for (j = 0; j < height; j++) { @@ -312,11 +313,11 @@ static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic, return p; dst[i] = p; - if (rgb_pic) + if (rgb_dst) AV_WB24(rgb_dst + i * 3, pal[p]); } dst += stride; - rgb_dst += rgb_stride; + rgb_dst = FF_PTR_ADD(rgb_dst, rgb_stride); } return 0; @@ -476,17 +477,19 @@ static int decode_region_intra(SliceContext *sc, ArithCoder *acoder, ptrdiff_t stride = c->pal_stride; ptrdiff_t rgb_stride = c->rgb_stride; uint8_t *dst = c->pal_pic + x + y * stride; - uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * rgb_stride; + uint8_t *rgb_dst = c->rgb_pic ? c->rgb_pic + x * 3 + y * rgb_stride : NULL; pix = decode_pixel(acoder, &sc->intra_pix_ctx, NULL, 0, 0); if (pix < 0) return pix; rgb_pix = c->pal[pix]; - for (i = 0; i < height; i++, dst += stride, rgb_dst += rgb_stride) { + for (i = 0; i < height; i++, dst += stride) { memset(dst, pix, width); - if (c->rgb_pic) + if (rgb_dst) { for (j = 0; j < width * 3; j += 3) AV_WB24(rgb_dst + j, rgb_pix); + rgb_dst += rgb_stride; + } } } else { return decode_region(acoder, c->pal_pic, c->rgb_pic, -- 2.27.0
>From 4e8f3682487228eb5e440ae7a4cbe09871dd831d Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 15:12:10 +0100 Subject: [PATCH 11/17] avcodec/vmdvideo: Fix NULL + 0 Affected the FATE tests filter-gradfun-sample and sierra-vmd-video. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- I think that the offset can actually be nonzero for the right input and have therefore not used FF_PTR_ADD. libavcodec/vmdvideo.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/libavcodec/vmdvideo.c b/libavcodec/vmdvideo.c index c1dc5b9696..bb9306e4ff 100644 --- a/libavcodec/vmdvideo.c +++ b/libavcodec/vmdvideo.c @@ -194,7 +194,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) unsigned char len; int ofs; - int frame_x, frame_y; + int frame_x, frame_y, prev_linesize; int frame_width, frame_height; frame_x = AV_RL16(&s->buf[6]); @@ -282,7 +282,13 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) } dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x]; - pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x]; + if (s->prev_frame->data[0]) { + prev_linesize = s->prev_frame->linesize[0]; + pp = s->prev_frame->data[0] + frame_y * prev_linesize + frame_x; + } else { + pp = NULL; + prev_linesize = 0; + } switch (meth) { case 1: for (i = 0; i < frame_height; i++) { @@ -298,7 +304,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) ofs += len; } else { /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame->data[0]) + if (ofs + len + 1 > frame_width || !pp) return AVERROR_INVALIDDATA; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -311,7 +317,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; } dp += frame->linesize[0]; - pp += s->prev_frame->linesize[0]; + pp = FF_PTR_ADD(pp, prev_linesize); } break; @@ -319,7 +325,6 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) for (i = 0; i < frame_height; i++) { bytestream2_get_buffer(&gb, dp, frame_width); dp += frame->linesize[0]; - pp += s->prev_frame->linesize[0]; } break; @@ -347,7 +352,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) } } else { /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame->data[0]) + if (ofs + len + 1 > frame_width || !pp) return AVERROR_INVALIDDATA; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -360,7 +365,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; } dp += frame->linesize[0]; - pp += s->prev_frame->linesize[0]; + pp = FF_PTR_ADD(pp, prev_linesize); } break; } -- 2.27.0
>From 7718cfbfa8a90e1e8f9ff62312efb08dcc21672e Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 16:03:27 +0100 Subject: [PATCH 12/17] avutil/base64: Fix undefined NULL + 0 Affected the base64 FATE test. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- Maybe this function should be switched to using indices? (Or casts to uintptr_t?) libavutil/base64.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavutil/base64.c b/libavutil/base64.c index 25ae8c411c..a1316b9438 100644 --- a/libavutil/base64.c +++ b/libavutil/base64.c @@ -79,12 +79,16 @@ static const uint8_t map2[256] = int av_base64_decode(uint8_t *out, const char *in_str, int out_size) { uint8_t *dst = out; - uint8_t *end = out + out_size; + uint8_t *end; // no sign extension const uint8_t *in = in_str; unsigned bits = 0xff; unsigned v; + if (!out) + goto validity_check; + + end = out + out_size; while (end - dst > 3) { BASE64_DEC_STEP(0); BASE64_DEC_STEP(1); @@ -108,6 +112,7 @@ int av_base64_decode(uint8_t *out, const char *in_str, int out_size) *dst++ = v; in += 4; } +validity_check: while (1) { BASE64_DEC_STEP(0); in++; @@ -126,7 +131,7 @@ out2: *dst++ = v >> 4; out1: out0: - return bits & 1 ? AVERROR_INVALIDDATA : dst - out; + return bits & 1 ? AVERROR_INVALIDDATA : out ? dst - out : 0; } /***************************************************************************** -- 2.27.0
>From f1d86543b3b2f3e007458f527cf018001e0e6f8d Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 16:17:04 +0100 Subject: [PATCH 13/17] avcodec/g2meet: Fix undefined NULL + 0 Affected the g2m4 FATE-test. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavcodec/g2meet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index 68b1b9dc74..da910c1e59 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -1029,7 +1029,7 @@ static int kempf_restore_buf(const uint8_t *src, int len, else if (npal <= 16) nb = 4; else nb = 8; - for (j = 0; j < height; j++, dst += stride, jpeg_tile += tile_stride) { + for (j = 0; j < height; j++, dst += stride, jpeg_tile = FF_PTR_ADD(jpeg_tile, tile_stride)) { if (get_bits(&gb, 8)) continue; for (i = 0; i < width; i++) { -- 2.27.0
>From 2c588ce4e69a28ac48870dcf90f9eeea15b0e24c Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 16:24:59 +0100 Subject: [PATCH 14/17] avfilter/vf_codecview: Fix undefined left shifts of negative numbers Affected the filter-codecview-mvs FATE-test. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavfilter/vf_codecview.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c index 197dc96136..28ac2df72f 100644 --- a/libavfilter/vf_codecview.c +++ b/libavfilter/vf_codecview.c @@ -141,7 +141,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, } buf += sx + sy * stride; ex -= sx; - f = ((ey - sy) << 16) / ex; + f = ((ey - sy) * (1 << 16)) / ex; for (x = 0; x <= ex; x++) { y = (x * f) >> 16; fr = (x * f) & 0xFFFF; @@ -156,7 +156,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, buf += sx + sy * stride; ey -= sy; if (ey) - f = ((ex - sx) << 16) / ey; + f = ((ex - sx) * (1 << 16)) / ey; else f = 0; for(y= 0; y <= ey; y++){ @@ -199,8 +199,8 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int length = sqrt((rx * rx + ry * ry) << 8); // FIXME subpixel accuracy - rx = ROUNDED_DIV(rx * 3 << 4, length); - ry = ROUNDED_DIV(ry * 3 << 4, length); + rx = ROUNDED_DIV(rx * (3 << 4), length); + ry = ROUNDED_DIV(ry * (3 << 4), length); if (tail) { rx = -rx; -- 2.27.0
>From 6e918d131e9d8b8bdf75c79b76743efb7fc95381 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 18:18:05 +0100 Subject: [PATCH 15/17] avcodec/motion_est: Fix invalid left shift of negative numbers Affected many FATE-tests. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavcodec/motion_est.c | 46 ++++++++++++++++---------------- libavcodec/motion_est_template.c | 17 ++++++------ 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index 5a339fc1c7..5b0958733c 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -109,8 +109,8 @@ static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, co me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel){ MotionEstContext * const c= &s->me; const int stride= c->stride; - const int hx= subx + (x<<(1+qpel)); - const int hy= suby + (y<<(1+qpel)); + const int hx = subx + x * (1 << (1 + qpel)); + const int hy = suby + y * (1 << (1 + qpel)); uint8_t * const * const ref= c->ref[ref_index]; uint8_t * const * const src= c->src[src_index]; int d; @@ -599,7 +599,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; - if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift); + if (P_LEFT[0] > c->xmax * (1 << shift)) P_LEFT[0] = c->xmax * (1 << shift); /* special case for first line */ if (s->first_slice_line && block<2) { @@ -610,10 +610,10 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0]; P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1]; - if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1] = (c->ymax<<shift); - if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift); - if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift); - if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift); + if (P_TOP[1] > c->ymax * (1 << shift)) P_TOP[1] = c->ymax * (1 << shift); + if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift); + if (P_TOPRIGHT[0] > c->xmax * (1 << shift)) P_TOPRIGHT[0] = c->xmax * (1 << shift); + if (P_TOPRIGHT[1] > c->ymax * (1 << shift)) P_TOPRIGHT[1] = c->ymax * (1 << shift); P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); @@ -629,8 +629,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) continue; if (i>4 && i<9) continue; - if(P[i][0] > (c->xmax<<shift)) P[i][0]= (c->xmax<<shift); - if(P[i][1] > (c->ymax<<shift)) P[i][1]= (c->ymax<<shift); + if (P[i][0] > c->xmax * (1 << shift)) P[i][0] = c->xmax * (1 << shift); + if (P[i][1] > c->ymax * (1 << shift)) P[i][1] = c->ymax * (1 <<shift ); } dmin4 = epzs_motion_search2(s, &mx4, &my4, P, block, block, s->p_mv_table, (1<<16)>>shift, 1); @@ -785,7 +785,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index, P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0]; P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1]; if(P_TOP[1] > (c->ymax<<1)) P_TOP[1] = (c->ymax<<1); - if(P_TOPRIGHT[0] < (c->xmin<<1)) P_TOPRIGHT[0]= (c->xmin<<1); + if (P_TOPRIGHT[0] < c->xmin * (1 << 1)) P_TOPRIGHT[0] = c->xmin * (1 << 1); if(P_TOPRIGHT[0] > (c->xmax<<1)) P_TOPRIGHT[0]= (c->xmax<<1); if(P_TOPRIGHT[1] > (c->ymax<<1)) P_TOPRIGHT[1]= (c->ymax<<1); @@ -839,7 +839,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index, dmin_sum += best_dmin; } - c->ymin<<=1; + c->ymin *= 2; c->ymax<<=1; c->stride>>=1; c->uvstride>>=1; @@ -981,8 +981,8 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, if(mx || my) mb_type |= CANDIDATE_MB_TYPE_SKIPPED; //FIXME check difference }else{ - mx <<=shift; - my <<=shift; + mx *= 1 << shift; + my *= 1 << shift; } if ((s->avctx->flags & AV_CODEC_FLAG_4MV) && !c->skip && varc>50<<8 && vard>10<<8){ @@ -1143,7 +1143,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y, P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1][0]; P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1][1]; if (P_TOP[1] > (c->ymax << shift)) P_TOP[1] = (c->ymax << shift); - if (P_TOPRIGHT[0] < (c->xmin << shift)) P_TOPRIGHT[0] = (c->xmin << shift); + if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift); if (P_TOPRIGHT[1] > (c->ymax << shift)) P_TOPRIGHT[1] = (c->ymax << shift); P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); @@ -1155,7 +1155,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y, if(mv_table == s->b_forw_mv_table){ mv_scale= (s->pb_time<<16) / (s->pp_time<<shift); }else{ - mv_scale= ((s->pb_time - s->pp_time)<<16) / (s->pp_time<<shift); + mv_scale = ((s->pb_time - s->pp_time) * (1 << 16)) / (s->pp_time<<shift); } dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, ref_index, s->p_mv_table, mv_scale, 0, 16); @@ -1255,8 +1255,8 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y) const int flags= c->sub_flags; const int qpel= flags&FLAG_QPEL; const int shift= 1+qpel; - const int xmin= c->xmin<<shift; - const int ymin= c->ymin<<shift; + const int xmin= c->xmin * (1 << shift); + const int ymin= c->ymin * (1 << shift); const int xmax= c->xmax<<shift; const int ymax= c->ymax<<shift; #define HASH(fx,fy,bx,by) ((fx)+17*(fy)+63*(bx)+117*(by)) @@ -1454,15 +1454,15 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) c->pred_x=0; c->pred_y=0; - P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin<<shift, xmax<<shift); - P_LEFT[1] = av_clip(mv_table[mot_xy - 1][1], ymin<<shift, ymax<<shift); + P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin * (1 << shift), xmax << shift); + P_LEFT[1] = av_clip(mv_table[mot_xy - 1][1], ymin * (1 << shift), ymax << shift); /* special case for first line */ if (!s->first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped - P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin<<shift, xmax<<shift); - P_TOP[1] = av_clip(mv_table[mot_xy - mot_stride ][1], ymin<<shift, ymax<<shift); - P_TOPRIGHT[0] = av_clip(mv_table[mot_xy - mot_stride + 1 ][0], xmin<<shift, xmax<<shift); - P_TOPRIGHT[1] = av_clip(mv_table[mot_xy - mot_stride + 1 ][1], ymin<<shift, ymax<<shift); + P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin * (1 << shift), xmax << shift); + P_TOP[1] = av_clip(mv_table[mot_xy - mot_stride ][1], ymin * (1 << shift), ymax << shift); + P_TOPRIGHT[0] = av_clip(mv_table[mot_xy - mot_stride + 1][0], xmin * (1 << shift), xmax << shift); + P_TOPRIGHT[1] = av_clip(mv_table[mot_xy - mot_stride + 1][1], ymin * (1 << shift), ymax << shift); P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c index d3b2f97744..6ab0ea13dc 100644 --- a/libavcodec/motion_est_template.c +++ b/libavcodec/motion_est_template.c @@ -82,7 +82,7 @@ static int hpel_motion_search(MpegEncContext * s, if (mx > xmin && mx < xmax && my > ymin && my < ymax) { int d= dmin; - const int index= (my<<ME_MAP_SHIFT) + mx; + const int index = my * (1 << ME_MAP_SHIFT) + mx; const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] + (mv_penalty[bx - pred_x] + mv_penalty[by-2 - pred_y])*c->penalty_factor; const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)] @@ -95,13 +95,13 @@ static int hpel_motion_search(MpegEncContext * s, #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1 unsigned key; unsigned map_generation= c->map_generation; - key= ((my-1)<<ME_MAP_MV_BITS) + (mx) + map_generation; + key = (my - 1) * (1 << ME_MAP_MV_BITS) + (mx) + map_generation; av_assert2(c->map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key); - key= ((my+1)<<ME_MAP_MV_BITS) + (mx) + map_generation; + key = (my + 1) * (1 << ME_MAP_MV_BITS) + (mx) + map_generation; av_assert2(c->map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key); - key= ((my)<<ME_MAP_MV_BITS) + (mx+1) + map_generation; + key = (my) * (1 << ME_MAP_MV_BITS) + (mx + 1) + map_generation; av_assert2(c->map[(index+1)&(ME_MAP_SIZE-1)] == key); - key= ((my)<<ME_MAP_MV_BITS) + (mx-1) + map_generation; + key = (my) * (1 << ME_MAP_MV_BITS) + (mx - 1) + map_generation; av_assert2(c->map[(index-1)&(ME_MAP_SIZE-1)] == key); #endif if(t<=b){ @@ -246,7 +246,7 @@ static int qpel_motion_search(MpegEncContext * s, int bx=4*mx, by=4*my; int d= dmin; int i, nx, ny; - const int index= (my<<ME_MAP_SHIFT) + mx; + const int index = my * (1 << ME_MAP_SHIFT) + mx; const int t= score_map[(index-(1<<ME_MAP_SHIFT) )&(ME_MAP_SIZE-1)]; const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)]; const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)]; @@ -299,7 +299,8 @@ static int qpel_motion_search(MpegEncContext * s, const int cy2= b + t - 2*c; int cxy; - if(map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)] == ((my-1)<<ME_MAP_MV_BITS) + (mx-1) + map_generation){ + if (map[(index - (1 << ME_MAP_SHIFT) - 1) & (ME_MAP_SIZE - 1)] == + (my - 1) * (1 << ME_MAP_MV_BITS) + (mx - 1) + map_generation) { tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)]; }else{ tl= cmp(s, mx-1, my-1, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);//FIXME wrong if chroma me is different @@ -328,7 +329,7 @@ static int qpel_motion_search(MpegEncContext * s, for(i=0; i<8; i++){ if(score < best[i]){ memmove(&best[i+1], &best[i], sizeof(int)*(7-i)); - memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i)); + memmove(best_pos[i + 1], best_pos[i], sizeof(best_pos[0]) * (7 - i)); best[i]= score; best_pos[i][0]= nx + 4*mx; best_pos[i][1]= ny + 4*my; -- 2.27.0
>From f836542e98f57df82af2f2a89c49feb53d2f532b Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 18:22:24 +0100 Subject: [PATCH 16/17] avutil/pixdesc: Fix 1 << 32 Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavutil/pixdesc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 2a919461a5..18c7a0efc8 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2659,7 +2659,7 @@ void ff_check_pixfmt_descriptors(void){ continue; av_read_image_line(tmp, (void*)data, linesize, d, 0, 0, j, 2, 0); av_assert0(tmp[0] == 0 && tmp[1] == 0); - tmp[0] = tmp[1] = (1<<c->depth) - 1; + tmp[0] = tmp[1] = (1ULL << c->depth) - 1; av_write_image_line(tmp, data, linesize, d, 0, 0, j, 2); } } -- 2.27.0
>From e62a903f14d9b50a6e7c5f1e90e67708299867df Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@gmail.com> Date: Fri, 26 Mar 2021 18:35:25 +0100 Subject: [PATCH 17/17] avcodec/flashsv2enc: Fix undefined NULL + 0 Affected the vsynth*-flashsv2 FATE-tests. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavcodec/flashsv2enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c index 430b6806c8..00aedf0795 100644 --- a/libavcodec/flashsv2enc.c +++ b/libavcodec/flashsv2enc.c @@ -159,7 +159,7 @@ static void init_blocks(FlashSV2Context * s, Block * blocks, b->enc = encbuf; b->data = databuf; encbuf += b->width * b->height * 3; - databuf += !databuf ? 0 : b->width * b->height * 6; + databuf = databuf ? databuf + b->width * b->height * 6 : NULL; } } } -- 2.27.0
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".