X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Favpacket.c;h=8988ca20d95f0f78d22f92a2b8874448a041360a;hb=e826ceeb5594c5e63860ec5e5050f86307456898;hp=9cdfafd8649549e670d2e378840ae7cb72bdf34a;hpb=483e9d8a2bb46ffaff8c41af7a7be01ebd7458df;p=ffmpeg diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 9cdfafd8649..8988ca20d95 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); @@ -568,16 +582,18 @@ int av_packet_ref(AVPacket *dst, const AVPacket *src) if (ret < 0) goto fail; memcpy(dst->buf->data, src->data, src->size); + dst->data = dst->buf->data; } else { dst->buf = av_buffer_ref(src->buf); if (!dst->buf) { ret = AVERROR(ENOMEM); goto fail; } + dst->data = src->data; } dst->size = src->size; - dst->data = dst->buf->data; + return 0; fail: av_packet_free_side_data(dst);