From d1e14a9393af071259639d1493d507e2a38a26d2 Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 28 Apr 2008 21:42:52 +0000 Subject: [PATCH] Additional bulletproofing to hufftree decoding; reject underpopulated trees up-front. svn path=/trunk/vorbis/; revision=14811 --- doc/Vorbis_I_spec.pdf | Bin 409861 -> 409861 bytes examples/decoder_example.c | 175 +++++++++++++++++++++++---------------------- lib/block.c | 9 ++- lib/sharedbook.c | 9 ++- 4 files changed, 103 insertions(+), 90 deletions(-) diff --git a/doc/Vorbis_I_spec.pdf b/doc/Vorbis_I_spec.pdf index af8695fbe42e98fa1ff5308d088229ed33f15888..fdf75e16b8580b1b4d08f7349af51fcec24ec1d3 100644 GIT binary patch delta 143 zcmZo|l5A~~Y-nL@VQOJ+VcEjE{=JTgk%gg!F_6?XFi|%!P}k(r_svgnNi0cK&~ULb zGBB_(fGgR4`#tNa0A~|3BR2zAH#ZjxXH#^b2m#@Gc!wb7ZW=L8$wE^ Jzi?oa1pqV$CNKa1 delta 143 zcmZo|l5A~~Y-nL@VQOJ+VcEjE{=JT|p@pHTp@FHfu7QcVfq}Xvm%eX)ic4Zis)B}# zm63sgg#ld2_S^4SPX#y|IJp^GT3VX8S-O~5S{fL-IGZ>*8X1_mSem*TT9~`oDcBHF KGW~@En=AkyQzh5{ diff --git a/examples/decoder_example.c b/examples/decoder_example.c index 2ca4205..1507773 100644 --- a/examples/decoder_example.c +++ b/examples/decoder_example.c @@ -198,108 +198,111 @@ int main(){ /* OK, got and parsed all three headers. Initialize the Vorbis packet->PCM decoder. */ - vorbis_synthesis_init(&vd,&vi); /* central decode state */ - vorbis_block_init(&vd,&vb); /* local state for most of the decode - so multiple block decodes can - proceed in parallel. We could init - multiple vorbis_block structures - for vd here */ - - /* The rest is just a straight decode loop until end of stream */ - while(!eos){ + if(vorbis_synthesis_init(&vd,&vi)==0){ /* central decode state */ + vorbis_block_init(&vd,&vb); /* local state for most of the decode + so multiple block decodes can + proceed in parallel. We could init + multiple vorbis_block structures + for vd here */ + + /* The rest is just a straight decode loop until end of stream */ while(!eos){ - int result=ogg_sync_pageout(&oy,&og); - if(result==0)break; /* need more data */ - if(result<0){ /* missing or corrupt data at this page position */ - fprintf(stderr,"Corrupt or missing data in bitstream; " - "continuing...\n"); - }else{ - ogg_stream_pagein(&os,&og); /* can safely ignore errors at - this point */ - while(1){ - result=ogg_stream_packetout(&os,&op); - - if(result==0)break; /* need more data */ - if(result<0){ /* missing or corrupt data at this page position */ - /* no reason to complain; already complained above */ - }else{ - /* we have a packet. Decode it */ - float **pcm; - int samples; - - if(vorbis_synthesis(&vb,&op)==0) /* test for success! */ - vorbis_synthesis_blockin(&vd,&vb); - /* - - **pcm is a multichannel float vector. In stereo, for - example, pcm[0] is left, and pcm[1] is right. samples is - the size of each channel. Convert the float values - (-1.<=range<=1.) to whatever PCM format and write it out */ + while(!eos){ + int result=ogg_sync_pageout(&oy,&og); + if(result==0)break; /* need more data */ + if(result<0){ /* missing or corrupt data at this page position */ + fprintf(stderr,"Corrupt or missing data in bitstream; " + "continuing...\n"); + }else{ + ogg_stream_pagein(&os,&og); /* can safely ignore errors at + this point */ + while(1){ + result=ogg_stream_packetout(&os,&op); - while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0){ - int j; - int clipflag=0; - int bout=(samples0){ + int j; + int clipflag=0; + int bout=(samples32767){ - val=32767; - clipflag=1; - } - if(val<-32768){ - val=-32768; - clipflag=1; + /* might as well guard against clipping */ + if(val>32767){ + val=32767; + clipflag=1; + } + if(val<-32768){ + val=-32768; + clipflag=1; + } + *ptr=val; + ptr+=vi.channels; } - *ptr=val; - ptr+=vi.channels; } - } - - if(clipflag) - fprintf(stderr,"Clipping in frame %ld\n",(long)(vd.sequence)); - - - fwrite(convbuffer,2*vi.channels,bout,stdout); - - vorbis_synthesis_read(&vd,bout); /* tell libvorbis how - many samples we - actually consumed */ - } + + if(clipflag) + fprintf(stderr,"Clipping in frame %ld\n",(long)(vd.sequence)); + + + fwrite(convbuffer,2*vi.channels,bout,stdout); + + vorbis_synthesis_read(&vd,bout); /* tell libvorbis how + many samples we + actually consumed */ + } + } } + if(ogg_page_eos(&og))eos=1; } - if(ogg_page_eos(&og))eos=1; + } + if(!eos){ + buffer=ogg_sync_buffer(&oy,4096); + bytes=fread(buffer,1,4096,stdin); + ogg_sync_wrote(&oy,bytes); + if(bytes==0)eos=1; } } - if(!eos){ - buffer=ogg_sync_buffer(&oy,4096); - bytes=fread(buffer,1,4096,stdin); - ogg_sync_wrote(&oy,bytes); - if(bytes==0)eos=1; - } + + /* ogg_page and ogg_packet structs always point to storage in + libvorbis. They're never freed or manipulated directly */ + + vorbis_block_clear(&vb); + vorbis_dsp_clear(&vd); + }else{ + fprintf(stderr,"Error: Corrupt header during playback initialization.\n"); } - + /* clean up this logical bitstream; before exit we see if we're followed by another [chained] */ - - ogg_stream_clear(&os); - - /* ogg_page and ogg_packet structs always point to storage in - libvorbis. They're never freed or manipulated directly */ - vorbis_block_clear(&vb); - vorbis_dsp_clear(&vd); - vorbis_comment_clear(&vc); + ogg_stream_clear(&os); + vorbis_comment_clear(&vc); vorbis_info_clear(&vi); /* must be called last */ } diff --git a/lib/block.c b/lib/block.c index 50ab425..10d4024 100644 --- a/lib/block.c +++ b/lib/block.c @@ -235,7 +235,8 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ if(!ci->fullbooks){ ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); for(i=0;ibooks;i++){ - vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]); + if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i])) + return -1; /* decode codebooks are now standalone after init */ vorbis_staticbook_destroy(ci->book_param[i]); ci->book_param[i]=NULL; @@ -694,9 +695,11 @@ int vorbis_synthesis_restart(vorbis_dsp_state *v){ } int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){ - if(_vds_shared_init(v,vi,0)) return 1; + if(_vds_shared_init(v,vi,0)){ + vorbis_dsp_clear(v); + return 1; + } vorbis_synthesis_restart(v); - return 0; } diff --git a/lib/sharedbook.c b/lib/sharedbook.c index 4b9f65f..14f22ef 100644 --- a/lib/sharedbook.c +++ b/lib/sharedbook.c @@ -124,7 +124,14 @@ ogg_uint32_t *_make_words(long *l,long n,long sparsecount){ }else if(sparsecount==0)count++; } - + + /* sanity check the huffman tree; an underpopulated tree must be rejected. */ + for(i=1;i<33;i++) + if(marker[i] & (0xffffffffUL>>(32-i))){ + _ogg_free(r); + return(NULL); + } + /* bitreverse the words because our bitwise packer/unpacker is LSb endian */ for(i=0,count=0;i