From 4b67376da7ded7f16dfebb8a05fb559ac7fbcf55 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 21 Jan 2015 01:17:41 +0000 Subject: [PATCH] Remove multiple subtly different inline and static implementaitonos of ilog() Add a few additional sanity checks, mostly functioning to ensure we're always calling ilog() with >=0 input. svn path=/trunk/vorbis/; revision=19441 --- lib/block.c | 29 +++++++++++++++-------------- lib/codebook.c | 8 ++++---- lib/codebook.h | 1 - lib/floor0.c | 2 +- lib/floor1.c | 35 +++++++++-------------------------- lib/info.c | 22 ++++++++-------------- lib/mapping0.c | 22 ++++++++-------------- lib/misc.h | 1 + lib/res0.c | 13 ++----------- lib/sharedbook.c | 14 ++++++-------- lib/synthesis.c | 18 +++++++----------- 11 files changed, 61 insertions(+), 104 deletions(-) diff --git a/lib/block.c b/lib/block.c index dfcd843..7fdf6ef 100644 --- a/lib/block.c +++ b/lib/block.c @@ -31,16 +31,6 @@ #include "registry.h" #include "misc.h" -static int ilog2(unsigned int v){ - int ret=0; - if(v)--v; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - /* pcm accumulator examples (not exhaustive): <-------------- lW ----------------> @@ -184,14 +174,19 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ private_state *b=NULL; int hs; - if(ci==NULL) return 1; + if(ci==NULL|| + ci->modes<=0|| + ci->blocksizes[0]<64|| + ci->blocksizes[1]blocksizes[0]){ + return 1; + } hs=ci->halfrate_flag; memset(v,0,sizeof(*v)); b=v->backend_state=_ogg_calloc(1,sizeof(*b)); v->vi=vi; - b->modebits=ilog2(ci->modes); + b->modebits=ov_ilog(ci->modes-1); b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0])); b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1])); @@ -204,8 +199,14 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs); /* Vorbis I uses only window type 0 */ - b->window[0]=ilog2(ci->blocksizes[0])-6; - b->window[1]=ilog2(ci->blocksizes[1])-6; + /* note that the correct computation below is technically: + b->window[0]=ov_ilog(ci->blocksizes[0]-1)-6; + b->window[1]=ov_ilog(ci->blocksizes[1]-1)-6; + but since blocksizes are always powers of two, + the below is equivalent. + */ + b->window[0]=ov_ilog(ci->blocksizes[0])-7; + b->window[1]=ov_ilog(ci->blocksizes[1])-7; if(encp){ /* encode/decode differ here */ diff --git a/lib/codebook.c b/lib/codebook.c index db0066c..7ec6311 100644 --- a/lib/codebook.c +++ b/lib/codebook.c @@ -57,12 +57,12 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){ char last=c->lengthlist[i-1]; if(this>last){ for(j=last;jentries-count)); + oggpack_write(opb,i-count,ov_ilog(c->entries-count)); count=i; } } } - oggpack_write(opb,i-count,_ilog(c->entries-count)); + oggpack_write(opb,i-count,ov_ilog(c->entries-count)); }else{ /* length random. Again, we don't code the codeword itself, just @@ -159,7 +159,7 @@ static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){ s->entries=oggpack_read(opb,24); if(s->entries==-1)goto _eofout; - if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout; + if(ov_ilog(s->dim)+ov_ilog(s->entries)>24)goto _eofout; /* codeword ordering.... length ordered or unordered? */ switch((int)oggpack_read(opb,1)){ @@ -203,7 +203,7 @@ static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){ s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries); for(i=0;ientries;){ - long num=oggpack_read(opb,_ilog(s->entries-i)); + long num=oggpack_read(opb,ov_ilog(s->entries-i)); if(num==-1)goto _eofout; if(length>32 || num>s->entries-i || (num>0 && (num-1)>>(length-1)>1)){ diff --git a/lib/codebook.h b/lib/codebook.h index 4c83af5..014e1e1 100644 --- a/lib/codebook.h +++ b/lib/codebook.h @@ -89,7 +89,6 @@ extern float *_book_logdist(const static_codebook *b,float *vals); extern float _float32_unpack(long val); extern long _float32_pack(float val); extern int _best(codebook *book, float *a, int step); -extern int _ilog(unsigned int v); extern long _book_maptype1_quantvals(const static_codebook *b); extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul); diff --git a/lib/floor0.c b/lib/floor0.c index 7827f50..b4402e6 100644 --- a/lib/floor0.c +++ b/lib/floor0.c @@ -168,7 +168,7 @@ static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){ if(ampraw>0){ /* also handles the -1 out of data case */ long maxval=(1<ampbits)-1; float amp=(float)ampraw/maxval*info->ampdB; - int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); + int booknum=oggpack_read(&vb->opb,ov_ilog(info->numbooks)); if(booknum!=-1 && booknumnumbooks){ /* be paranoid */ codec_setup_info *ci=vb->vd->vi->codec_setup; diff --git a/lib/floor1.c b/lib/floor1.c index 54527ac..49ef52d 100644 --- a/lib/floor1.c +++ b/lib/floor1.c @@ -72,25 +72,6 @@ static void floor1_free_look(vorbis_look_floor *i){ } } -static int ilog(unsigned int v){ - int ret=0; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -static int ilog2(unsigned int v){ - int ret=0; - if(v)--v; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){ vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; int j,k; @@ -117,8 +98,10 @@ static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){ /* save out the post list */ oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */ - oggpack_write(opb,ilog2(maxposit),4); - rangebits=ilog2(maxposit); + /* maxposit cannot legally be less than 1; this is encode-side, we + can assume our setup is OK */ + oggpack_write(opb,ov_ilog(maxposit-1),4); + rangebits=ov_ilog(maxposit-1); for(j=0,k=0;jpartitions;j++){ count+=info->class_dim[info->partitionclass[j]]; @@ -854,9 +837,9 @@ int floor1_encode(oggpack_buffer *opb,vorbis_block *vb, /* beginning/end post */ look->frames++; - look->postbits+=ilog(look->quant_q-1)*2; - oggpack_write(opb,out[0],ilog(look->quant_q-1)); - oggpack_write(opb,out[1],ilog(look->quant_q-1)); + look->postbits+=ov_ilog(look->quant_q-1)*2; + oggpack_write(opb,out[0],ov_ilog(look->quant_q-1)); + oggpack_write(opb,out[1],ov_ilog(look->quant_q-1)); /* partition by partition */ @@ -980,8 +963,8 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){ if(oggpack_read(&vb->opb,1)==1){ int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value)); - fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); - fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); + fit_value[0]=oggpack_read(&vb->opb,ov_ilog(look->quant_q-1)); + fit_value[1]=oggpack_read(&vb->opb,ov_ilog(look->quant_q-1)); /* partition by partition */ for(i=0,j=2;ipartitions;i++){ diff --git a/lib/info.c b/lib/info.c index fed4582..e447a0c 100644 --- a/lib/info.c +++ b/lib/info.c @@ -35,16 +35,6 @@ #define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20150105 (⛄⛄⛄⛄)" /* helpers */ -static int ilog2(unsigned int v){ - int ret=0; - if(v)--v; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - static void _v_writestring(oggpack_buffer *o,const char *s, int bytes){ while(bytes--){ @@ -447,7 +437,11 @@ int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op) static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){ codec_setup_info *ci=vi->codec_setup; - if(!ci)return(OV_EFAULT); + if(!ci|| + ci->blocksizes[0]<64|| + ci->blocksizes[1]blocksizes[0]){ + return(OV_EFAULT); + } /* preamble */ oggpack_write(opb,0x01,8); @@ -462,8 +456,8 @@ static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){ oggpack_write(opb,vi->bitrate_nominal,32); oggpack_write(opb,vi->bitrate_lower,32); - oggpack_write(opb,ilog2(ci->blocksizes[0]),4); - oggpack_write(opb,ilog2(ci->blocksizes[1]),4); + oggpack_write(opb,ov_ilog(ci->blocksizes[0]-1),4); + oggpack_write(opb,ov_ilog(ci->blocksizes[1]-1),4); oggpack_write(opb,1,1); return(0); @@ -589,7 +583,7 @@ int vorbis_analysis_headerout(vorbis_dsp_state *v, oggpack_buffer opb; private_state *b=v->backend_state; - if(!b){ + if(!b||vi->channels<=0){ ret=OV_EFAULT; goto err_out; } diff --git a/lib/mapping0.c b/lib/mapping0.c index e0be6a0..8a7a04c 100644 --- a/lib/mapping0.c +++ b/lib/mapping0.c @@ -45,16 +45,6 @@ static void mapping0_free_info(vorbis_info_mapping *i){ } } -static int ilog(unsigned int v){ - int ret=0; - if(v)--v; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm, oggpack_buffer *opb){ int i; @@ -78,8 +68,8 @@ static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm, oggpack_write(opb,info->coupling_steps-1,8); for(i=0;icoupling_steps;i++){ - oggpack_write(opb,info->coupling_mag[i],ilog(vi->channels)); - oggpack_write(opb,info->coupling_ang[i],ilog(vi->channels)); + oggpack_write(opb,info->coupling_mag[i],ov_ilog(vi->channels-1)); + oggpack_write(opb,info->coupling_ang[i],ov_ilog(vi->channels-1)); } }else oggpack_write(opb,0,1); @@ -104,6 +94,7 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb) vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info)); codec_setup_info *ci=vi->codec_setup; memset(info,0,sizeof(*info)); + if(vi->channels<=0)goto err_out; b=oggpack_read(opb,1); if(b<0)goto err_out; @@ -119,8 +110,11 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb) info->coupling_steps=oggpack_read(opb,8)+1; if(info->coupling_steps<=0)goto err_out; for(i=0;icoupling_steps;i++){ - int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels)); - int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels)); + /* vi->channels > 0 is enforced in the caller */ + int testM=info->coupling_mag[i]= + oggpack_read(opb,ov_ilog(vi->channels-1)); + int testA=info->coupling_ang[i]= + oggpack_read(opb,ov_ilog(vi->channels-1)); if(testM<0 || testA<0 || diff --git a/lib/misc.h b/lib/misc.h index b5f8a4a..a6eaa90 100644 --- a/lib/misc.h +++ b/lib/misc.h @@ -21,6 +21,7 @@ extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes); extern void _vorbis_block_ripcord(vorbis_block *vb); +extern int ov_ilog(unsigned int v); #ifdef ANALYSIS extern int analysis_noisy; diff --git a/lib/res0.c b/lib/res0.c index bca6e47..837f5fd 100644 --- a/lib/res0.c +++ b/lib/res0.c @@ -152,15 +152,6 @@ void res0_free_look(vorbis_look_residue *i){ } } -static int ilog(unsigned int v){ - int ret=0; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - static int icount(unsigned int v){ int ret=0; while(v){ @@ -186,7 +177,7 @@ void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){ bitmask of one indicates this partition class has bits to write this pass */ for(j=0;jpartitions;j++){ - if(ilog(info->secondstages[j])>3){ + if(ov_ilog(info->secondstages[j])>3){ /* yes, this is a minor hack due to not thinking ahead */ oggpack_write(opb,info->secondstages[j],3); oggpack_write(opb,1,1); @@ -284,7 +275,7 @@ vorbis_look_residue *res0_look(vorbis_dsp_state *vd, look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks)); for(j=0;jparts;j++){ - int stages=ilog(info->secondstages[j]); + int stages=ov_ilog(info->secondstages[j]); if(stages){ if(stages>maxstage)maxstage=stages; look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j])); diff --git a/lib/sharedbook.c b/lib/sharedbook.c index d389f67..926b0fb 100644 --- a/lib/sharedbook.c +++ b/lib/sharedbook.c @@ -26,13 +26,11 @@ #include "scales.h" /**** pack/unpack helpers ******************************************/ -int _ilog(unsigned int v){ - int ret=0; - while(v){ - ret++; - v>>=1; - } - return(ret); + +int ov_ilog(ogg_uint32_t v){ + int ret; + for(ret=0;v;ret++)v>>=1; + return ret; } /* 32 bit float (not IEEE; nonnormalized mantissa + @@ -374,7 +372,7 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ if(s->lengthlist[i]>0) c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; - c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ + c->dec_firsttablen=ov_ilog(c->used_entries)-4; /* this is magic */ if(c->dec_firsttablen<5)c->dec_firsttablen=5; if(c->dec_firsttablen>8)c->dec_firsttablen=8; diff --git a/lib/synthesis.c b/lib/synthesis.c index f55091f..3fa5ab9 100644 --- a/lib/synthesis.c +++ b/lib/synthesis.c @@ -145,6 +145,11 @@ long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ oggpack_buffer opb; int mode; + if(ci==NULL || ci->modes<=0){ + /* codec setup not properly intialized */ + return(OV_EFAULT); + } + oggpack_readinit(&opb,op->packet,op->bytes); /* Check the packet type */ @@ -153,17 +158,8 @@ long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ return(OV_ENOTAUDIO); } - { - int modebits=0; - int v=ci->modes; - while(v>1){ - modebits++; - v>>=1; - } - - /* read our mode and pre/post windowsize */ - mode=oggpack_read(&opb,modebits); - } + /* read our mode and pre/post windowsize */ + mode=oggpack_read(&opb,ov_ilog(ci->modes-1)); if(mode==-1 || !ci->mode_param[mode])return(OV_EBADPACKET); return(ci->blocksizes[ci->mode_param[mode]->blockflag]); } -- 2.7.4