aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndriy Lysnevych <andriy.lysnevych@gmail.com>2016-05-25 17:56:21 +0300
committerMichael Niedermayer <michael@niedermayer.cc>2016-06-02 00:52:22 +0200
commit2fe04630e7d9c32fcab847b482998fa9fa7224d8 (patch)
tree7a52b8742d29fd3f4c975abb521ff62db5d3f14d
parentd1efdd54f2bf034960df5e09165c6b4599e44022 (diff)
downloadffmpeg-2fe04630e7d9c32fcab847b482998fa9fa7224d8.tar.gz
avcodec/avpacket: Respect payload offset in av_grow_packet
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r--libavcodec/avpacket.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index bcc7c79de7..8988ca20d9 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -110,24 +110,38 @@ int av_grow_packet(AVPacket *pkt, int grow_by)
{
int new_size;
av_assert0((unsigned)pkt->size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE);
- if (!pkt->size)
- return av_new_packet(pkt, grow_by);
if ((unsigned)grow_by >
INT_MAX - (pkt->size + AV_INPUT_BUFFER_PADDING_SIZE))
return -1;
new_size = pkt->size + grow_by + AV_INPUT_BUFFER_PADDING_SIZE;
if (pkt->buf) {
- int ret = av_buffer_realloc(&pkt->buf, new_size);
- if (ret < 0)
- return ret;
+ size_t data_offset;
+ uint8_t *old_data = pkt->data;
+ if (pkt->data == NULL) {
+ data_offset = 0;
+ pkt->data = pkt->buf->data;
+ } else {
+ data_offset = pkt->data - pkt->buf->data;
+ if (data_offset > INT_MAX - new_size)
+ return -1;
+ }
+
+ if (new_size + data_offset > pkt->buf->size) {
+ int ret = av_buffer_realloc(&pkt->buf, new_size + data_offset);
+ if (ret < 0) {
+ pkt->data = old_data;
+ return ret;
+ }
+ pkt->data = pkt->buf->data + data_offset;
+ }
} else {
pkt->buf = av_buffer_alloc(new_size);
if (!pkt->buf)
return AVERROR(ENOMEM);
- memcpy(pkt->buf->data, pkt->data, FFMIN(pkt->size, pkt->size + grow_by));
+ memcpy(pkt->buf->data, pkt->data, pkt->size);
+ pkt->data = pkt->buf->data;
}
- pkt->data = pkt->buf->data;
pkt->size += grow_by;
memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);