summaryrefslogtreecommitdiff
path: root/libavcodec/avpacket.c
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2011-04-13 17:36:02 +0200
committerLuca Barbato <lu_zero@gentoo.org>2011-04-15 18:02:05 +0200
commitc0eee89337be5f5728e7da84aa15c658e07506ca (patch)
treeb7dc1a774827a08a4781fe7bbee1c6a310557a08 /libavcodec/avpacket.c
parent2d8591c27e2dc582a7020e2580e16278dbfbddff (diff)
make av_dup_packet() more cautious on allocation failures
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
Diffstat (limited to 'libavcodec/avpacket.c')
-rw-r--r--libavcodec/avpacket.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 4b1002f62b..e0e4df46f2 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -100,19 +100,19 @@ int av_grow_packet(AVPacket *pkt, int grow_by)
return 0;
}
-#define DUP_DATA(dst, size, padding) \
+#define DUP_DATA(dst, src, size, padding) \
do { \
void *data; \
if (padding) { \
if ((unsigned)(size) > (unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE) \
- return AVERROR(ENOMEM); \
+ goto failed_alloc; \
data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); \
} else { \
data = av_malloc(size); \
} \
if (!data) \
- return AVERROR(ENOMEM); \
- memcpy(data, dst, size); \
+ goto failed_alloc; \
+ memcpy(data, src, size); \
if (padding) \
memset((uint8_t*)data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); \
dst = data; \
@@ -120,20 +120,32 @@ int av_grow_packet(AVPacket *pkt, int grow_by)
int av_dup_packet(AVPacket *pkt)
{
+ AVPacket tmp_pkt;
+
if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct == NULL)) && pkt->data) {
- DUP_DATA(pkt->data, pkt->size, 1);
+ tmp_pkt = *pkt;
+
+ pkt->data = NULL;
+ pkt->side_data = NULL;
+ DUP_DATA(pkt->data, tmp_pkt.data, pkt->size, 1);
pkt->destruct = av_destruct_packet;
if (pkt->side_data_elems) {
int i;
- DUP_DATA(pkt->side_data, pkt->side_data_elems * sizeof(*pkt->side_data), 0);
+ DUP_DATA(pkt->side_data, tmp_pkt.side_data,
+ pkt->side_data_elems * sizeof(*pkt->side_data), 0);
+ memset(pkt->side_data, 0, pkt->side_data_elems * sizeof(*pkt->side_data));
for (i = 0; i < pkt->side_data_elems; i++) {
- DUP_DATA(pkt->side_data[i].data, pkt->side_data[i].size, 1);
+ DUP_DATA(pkt->side_data[i].data, tmp_pkt.side_data[i].data,
+ pkt->side_data[i].size, 1);
}
}
}
return 0;
+failed_alloc:
+ av_destruct_packet(pkt);
+ return AVERROR(ENOMEM);
}
void av_free_packet(AVPacket *pkt)