changeset 18708:9e2b300db17b

Change free_sh_audio() to take demuxer and stream id as parameters (same as new_sh_audio()) instead of sh_audio_t *, use those to remove the pointer from demuxer->a_streams[] before freeing it. Some demuxers use free_sh_audio() to undo the creation of an already-allocated audio stream in case of error. These uses were unsafe since free_sh_audio() freed the data structure but left the pointer in demuxer->a_streams[], leading to double free later in free_demuxer() (and perhaps use of the freed stream before that, I didn't check).
author uau
date Wed, 14 Jun 2006 14:05:59 +0000
parents 60a60dbf7a88
children 7ca8f5ab5136
files libmpdemux/demux_audio.c libmpdemux/demux_mkv.c libmpdemux/demux_viv.c libmpdemux/demuxer.c libmpdemux/stheader.h
diffstat 5 files changed, 10 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demux_audio.c	Wed Jun 14 13:47:11 2006 +0000
+++ b/libmpdemux/demux_audio.c	Wed Jun 14 14:05:59 2006 +0000
@@ -47,7 +47,6 @@
   struct mp3_hdr *next;
 } mp3_hdr_t;
 
-extern void free_sh_audio(sh_audio_t* sh);
 extern void print_wave_header(WAVEFORMATEX *h, int verbose_level);
 
 int hr_mp3_seek = 0;
@@ -412,12 +411,12 @@
     l = stream_read_dword_le(s);
     if(l < 16) {
       mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] Bad wav header length: too short (%d)!!!\n",l);
-      free_sh_audio(sh_audio);
+      free_sh_audio(demuxer, 0);
       return 0;
     }
     if(l > MAX_WAVHDR_LEN) {
       mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] Bad wav header length: too long (%d)!!!\n",l);
-      free_sh_audio(sh_audio);
+      free_sh_audio(demuxer, 0);
       return 0;
     }
     sh_audio->wf = w = (WAVEFORMATEX*)malloc(l > sizeof(WAVEFORMATEX) ? l : sizeof(WAVEFORMATEX));
--- a/libmpdemux/demux_mkv.c	Wed Jun 14 13:47:11 2006 +0000
+++ b/libmpdemux/demux_mkv.c	Wed Jun 14 14:05:59 2006 +0000
@@ -1837,7 +1837,7 @@
           mp_msg (MSGT_DEMUX, MSGL_WARN, "[mkv] Unknown/unsupported audio "
                   "codec ID '%s' for track %u or missing/faulty private "
                   "codec data.\n", track->codec_id, track->tnum);
-          free_sh_audio (sh_a);
+          free_sh_audio(demuxer, track->tnum);
           return 1;
         }
     }
@@ -2061,7 +2061,7 @@
     }
   else if (!track->ms_compat || (track->private_size < sizeof(WAVEFORMATEX)))
     {
-      free_sh_audio (sh_a);
+      free_sh_audio(demuxer, track->tnum);
       return 1;
     }
 
--- a/libmpdemux/demux_viv.c	Wed Jun 14 13:47:11 2006 +0000
+++ b/libmpdemux/demux_viv.c	Wed Jun 14 14:05:59 2006 +0000
@@ -663,7 +663,7 @@
 		{
 		    mp_msg(MSGT_DEMUX, MSGL_ERR, "VIVO: Not support audio codec (%d)\n",
 			priv->audio_codec);
-		    free_sh_audio(sh);
+		    free_sh_audio(demuxer, 1);
 		    goto nosound;
 		}
 
--- a/libmpdemux/demuxer.c	Wed Jun 14 13:47:11 2006 +0000
+++ b/libmpdemux/demuxer.c	Wed Jun 14 14:05:59 2006 +0000
@@ -229,7 +229,9 @@
     return demuxer->a_streams[id];
 }
 
-void free_sh_audio(sh_audio_t* sh){
+void free_sh_audio(demuxer_t *demuxer, int id) {
+    sh_audio_t *sh = demuxer->a_streams[id];
+    demuxer->a_streams[id] = NULL;
     mp_msg(MSGT_DEMUXER,MSGL_DBG2,"DEMUXER: freeing sh_audio at %p\n",sh);
     if(sh->wf) free(sh->wf);
     free(sh);
@@ -270,11 +272,9 @@
       goto skip_streamfree;
     // free streams:
     for(i = 0; i < MAX_A_STREAMS; i++)
-	if(demuxer->a_streams[i]) free_sh_audio(demuxer->a_streams[i]);
+	if(demuxer->a_streams[i]) free_sh_audio(demuxer, i);
     for(i = 0; i < MAX_V_STREAMS; i++)
 	if(demuxer->v_streams[i]) free_sh_video(demuxer->v_streams[i]);
-    //if(sh_audio) free_sh_audio(sh_audio);
-    //if(sh_video) free_sh_video(sh_video);
     // free demuxers:
     free_demuxer_stream(demuxer->audio);
     free_demuxer_stream(demuxer->video);
--- a/libmpdemux/stheader.h	Wed Jun 14 13:47:11 2006 +0000
+++ b/libmpdemux/stheader.h	Wed Jun 14 14:05:59 2006 +0000
@@ -89,7 +89,7 @@
 // demuxer.c:
 sh_audio_t* new_sh_audio(demuxer_t *demuxer,int id);
 sh_video_t* new_sh_video(demuxer_t *demuxer,int id);
-void free_sh_audio(sh_audio_t *sh);
+void free_sh_audio(demuxer_t *demuxer, int id);
 void free_sh_video(sh_video_t *sh);
 
 // video.c: