vorbisfile has a flaw where a bad link is not initialized [proper
authorMonty <xiphmont@xiph.org>
Tue, 2 Sep 2003 04:39:26 +0000 (04:39 +0000)
committerMonty <xiphmont@xiph.org>
Tue, 2 Sep 2003 04:39:26 +0000 (04:39 +0000)
behavior], but it would attempt to initialize and play that link
anyway, getting a segfault.  The easiest way to deal was to improve
libvorbis's error checking on dsp initialization if an app (in this
case, vorbisfile) tries to call init on a blank vorbis_info structure.

read and seek calls will now return 'OV_EBADLINK' in this case.

Monty

svn path=/trunk/vorbis/; revision=5278

lib/block.c
lib/vorbisfile.c

index 377b25a..9615b12 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.74 2003/08/27 05:29:24 xiphmont Exp $
+ last mod: $Id: block.c,v 1.75 2003/09/02 04:39:26 xiphmont Exp $
 
  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
  more amusing by Vorbis' current two allowed block sizes.
@@ -168,7 +168,10 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
   int i;
   codec_setup_info *ci=vi->codec_setup;
   private_state *b=NULL;
-  int hs=ci->halfrate_flag; 
+  int hs;
+
+  if(ci==NULL) return 1;
+  hs=ci->halfrate_flag; 
 
   memset(v,0,sizeof(*v));
   b=v->backend_state=_ogg_calloc(1,sizeof(*b));
@@ -259,14 +262,14 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
     b->residue[i]=_residue_P[ci->residue_type[i]]->
       look(v,ci->residue_param[i]);    
 
-  return(0);
+  return 0;
 }
 
 /* arbitrary settings and spec-mandated numbers get filled in here */
 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
   private_state *b=NULL;
 
-  _vds_shared_init(v,vi,1);
+  if(_vds_shared_init(v,vi,1))return 1;
   b=v->backend_state;
   b->psy_g_look=_vp_global_look(vi);
 
@@ -658,10 +661,10 @@ int vorbis_synthesis_restart(vorbis_dsp_state *v){
 }
 
 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
-  _vds_shared_init(v,vi,0);
+  if(_vds_shared_init(v,vi,0)) return 1;
   vorbis_synthesis_restart(v);
 
-  return(0);
+  return 0;
 }
 
 /* Unlike in analysis, the window is only partially applied for each
index 48c9afb..24011d7 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.72 2003/09/02 01:06:08 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.73 2003/09/02 04:39:26 xiphmont Exp $
 
  ********************************************************************/
 
@@ -387,18 +387,20 @@ static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
   }
 }
 
-static void _make_decode_ready(OggVorbis_File *vf){
-  if(vf->ready_state!=STREAMSET)return;
+static int _make_decode_ready(OggVorbis_File *vf){
+  if(vf->ready_state!=STREAMSET)return OV_EFAULT;
   if(vf->seekable){
-    vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
+    if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
+      return OV_EBADLINK;
   }else{
-    vorbis_synthesis_init(&vf->vd,vf->vi);
+    if(vorbis_synthesis_init(&vf->vd,vf->vi))
+      return OV_EBADLINK;
   }    
   vorbis_block_init(&vf->vd,&vf->vb);
   vf->ready_state=INITSET;
   vf->bittrack=0.f;
   vf->samptrack=0.f;
-  return;
+  return 0;
 }
 
 static int _open_seekable2(OggVorbis_File *vf){
@@ -611,7 +613,10 @@ static int _fetch_and_process_packet(OggVorbis_File *vf,
        }
       }
       
-      _make_decode_ready(vf);
+      {
+       int ret=_make_decode_ready(vf);
+       if(ret<0)return ret;
+      }
     }
     ogg_stream_pagein(&vf->os,&og);
   }
@@ -1258,7 +1263,7 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
   int thisblock,lastblock=0;
   int ret=ov_pcm_seek_page(vf,pos);
   if(ret<0)return(ret);
-  _make_decode_ready(vf);
+  if((ret=_make_decode_ready(vf)))return ret;
 
   /* discard leading packets we don't need for the lapping of the
      position we want; don't decode them */
@@ -1318,7 +1323,8 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
        
        ogg_stream_reset_serialno(&vf->os,vf->current_serialno); 
        vf->ready_state=STREAMSET;      
-       _make_decode_ready(vf);
+       ret=_make_decode_ready(vf);
+       if(ret)return ret;
        lastblock=0;
       }