[FFmpeg-cvslog] make av_dup_packet() more cautious on allocation failures

Kostya Shishkov git at videolan.org
Sun Apr 17 23:56:35 CEST 2011


ffmpeg | branch: master | Kostya Shishkov <kostya.shishkov at gmail.com> | Wed Apr 13 17:36:02 2011 +0200| [c0eee89337be5f5728e7da84aa15c658e07506ca] | committer: Luca Barbato

make av_dup_packet() more cautious on allocation failures

Signed-off-by: Luca Barbato <lu_zero at gentoo.org>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c0eee89337be5f5728e7da84aa15c658e07506ca
---

 libavcodec/avpacket.c |   26 +++++++++++++++++++-------
 1 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 4b1002f..e0e4df4 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)



More information about the ffmpeg-cvslog mailing list