# HG changeset patch # User uau # Date 1150293959 0 # Node ID 9e2b300db17b15ab27527f31fafffd61dc3bcd59 # Parent 60a60dbf7a889d3cf710930f9de28da75412eed4 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). diff -r 60a60dbf7a88 -r 9e2b300db17b libmpdemux/demux_audio.c --- 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)); diff -r 60a60dbf7a88 -r 9e2b300db17b libmpdemux/demux_mkv.c --- 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; } diff -r 60a60dbf7a88 -r 9e2b300db17b libmpdemux/demux_viv.c --- 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; } diff -r 60a60dbf7a88 -r 9e2b300db17b libmpdemux/demuxer.c --- 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); diff -r 60a60dbf7a88 -r 9e2b300db17b libmpdemux/stheader.h --- 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: