aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-03-18 00:07:53 +0100
committerMichael Niedermayer <michaelni@gmx.at>2014-06-25 16:18:39 +0200
commitd581567e0948e709c5ab995a1eaa91587797a12f (patch)
treec3c0f0f26768bb235e8e7dade2a99a8fa66ffa7e
parent9933e06595c0073785474e17be88d8fe442617ef (diff)
downloadffmpeg-d581567e0948e709c5ab995a1eaa91587797a12f.tar.gz
avcodec/utils: fix sizeof(AVFrame) dependence in avcodec_encode_audio2()
This is a bit tricky, we allocate a correctly sized AVFrame but then only copy the compile time AVFrame size, this is to ensure that user applications which do not use the correct av frame API dont end with out of array reads. Note, applications using the correct API have set extended_data and the changed code will never be executed for them. Signed-off-by: Michael Niedermayer <michaelni@gmx.at> (cherry picked from commit 8ab80707841a73ca7708e1e1aa97f3513fff3d35) Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/utils.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 5f58fb0ad2..7a45653430 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -1491,7 +1491,7 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
const AVFrame *frame,
int *got_packet_ptr)
{
- AVFrame tmp;
+ AVFrame *extended_frame = NULL;
AVFrame *padded_frame = NULL;
int ret;
AVPacket user_pkt = *avpkt;
@@ -1516,9 +1516,13 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
}
av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n");
- tmp = *frame;
- tmp.extended_data = tmp.data;
- frame = &tmp;
+ extended_frame = av_frame_alloc();
+ if (!extended_frame)
+ return AVERROR(ENOMEM);
+
+ memcpy(extended_frame, frame, sizeof(AVFrame));
+ extended_frame->extended_data = extended_frame->data;
+ frame = extended_frame;
}
/* check for valid frame size */
@@ -1526,14 +1530,15 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
if (avctx->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
if (frame->nb_samples > avctx->frame_size) {
av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n");
- return AVERROR(EINVAL);
+ ret = AVERROR(EINVAL);
+ goto end;
}
} else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {
if (frame->nb_samples < avctx->frame_size &&
!avctx->internal->last_audio_frame) {
ret = pad_last_frame(avctx, &padded_frame, frame);
if (ret < 0)
- return ret;
+ goto end;
frame = padded_frame;
avctx->internal->last_audio_frame = 1;
@@ -1605,6 +1610,7 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
end:
av_frame_free(&padded_frame);
+ av_free(extended_frame);
return ret;
}