diff options
author | Nedeljko Babic <nbabic@mips.com> | 2012-03-27 11:21:19 +0200 |
---|---|---|
committer | Nedeljko Babic <nbabic@mips.com> | 2012-04-03 15:38:02 +0200 |
commit | 2730389b0f05deb37e4f1abc42a736f61e8fa108 (patch) | |
tree | 808e6048155386e051b8c1ea9906eb6eeb0edec0 | |
parent | 72ee537239638fe480c569ee9e49877800c9dd37 (diff) | |
download | tremor-2730389b0f05deb37e4f1abc42a736f61e8fa108.tar.gz |
Port the rest of r16222 from libvorbis.
Commit additional hardening to setup packet decode.
[Import changes from Tremor (28854b5 2010-10-14)]
-rw-r--r-- | codebook.c | 2 | ||||
-rw-r--r-- | floor1.c | 2 | ||||
-rw-r--r-- | info.c | 26 | ||||
-rw-r--r-- | mapping0.c | 23 |
4 files changed, 34 insertions, 19 deletions
@@ -450,7 +450,7 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){ s->q_del=_float32_unpack(oggpack_read(opb,32),&s->q_delp); s->q_bits=oggpack_read(opb,4)+1; s->q_seq=oggpack_read(opb,1); - + if(s->q_seq==-1)goto _eofout; s->q_del>>=s->q_bits; s->q_delp+=s->q_bits; } @@ -95,6 +95,7 @@ vorbis_info_floor *floor1_info_unpack (vorbis_info *vi,oggpack_buffer *opb){ (char *)_ogg_malloc(info->partitions*sizeof(*info->partitionclass)); for(j=0;j<info->partitions;j++){ info->partitionclass[j]=(char)oggpack_read(opb,4); /* only 0 to 15 legal */ + if(info->partitionclass[j]<0)goto err_out; if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j]; } @@ -120,6 +121,7 @@ vorbis_info_floor *floor1_info_unpack (vorbis_info *vi,oggpack_buffer *opb){ /* read the post list */ info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */ rangebits=oggpack_read(opb,4); + if(rangebits<0)goto err_out; for(j=0,k=0;j<info->partitions;j++) count+=info->class[(int)info->partitionclass[j]].class_dim; @@ -59,7 +59,7 @@ char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){ strcpy(fulltag, tag); strcat(fulltag, "="); - + for(i=0;i<vc->comments;i++){ if(!tagcompare(vc->user_comments[i], fulltag, taglen)){ if(count == found) @@ -149,7 +149,7 @@ void vorbis_info_clear(vorbis_info *vi){ vorbis_book_clear(ci->book_param+i); _ogg_free(ci->book_param); } - + _ogg_free(ci); } @@ -174,7 +174,7 @@ static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ ci->blocksizes[0]=1<<oggpack_read(opb,4); ci->blocksizes[1]=1<<oggpack_read(opb,4); - + #ifdef LIMIT_TO_64kHz if(vi->rate>=64000 || ci->blocksizes[1]>4096)goto err_out; #else @@ -183,10 +183,10 @@ static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ if(vi->rate<1)goto err_out; if(vi->channels<1)goto err_out; - if(ci->blocksizes[0]<64)goto err_out; + if(ci->blocksizes[0]<64)goto err_out; if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out; if(ci->blocksizes[1]>8192)goto err_out; - + if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ return(0); @@ -205,14 +205,14 @@ static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ if(vc->comments<0)goto err_out; vc->user_comments=(char **)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); vc->comment_lengths=(int *)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); - + for(i=0;i<vc->comments;i++){ int len=oggpack_read(opb,32); if(len<0)goto err_out; vc->comment_lengths[i]=len; vc->user_comments[i]=(char *)_ogg_calloc(len+1,1); _v_readstring(opb,vc->user_comments[i],len); - } + } if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ return(0); @@ -230,6 +230,7 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ /* codebooks */ ci->books=oggpack_read(opb,8)+1; + if(ci->books<=0)goto err_out; ci->book_param=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->book_param)); for(i=0;i<ci->books;i++) if(vorbis_book_unpack(opb,ci->book_param+i))goto err_out; @@ -241,6 +242,7 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ /* floor backend settings */ ci->floors=oggpack_read(opb,6)+1; + if(ci->floors<=0)goto err_out; ci->floor_param=_ogg_malloc(sizeof(*ci->floor_param)*ci->floors); ci->floor_type=_ogg_malloc(sizeof(*ci->floor_type)*ci->floors); for(i=0;i<ci->floors;i++){ @@ -255,20 +257,23 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ /* residue backend settings */ ci->residues=oggpack_read(opb,6)+1; + if(ci->residues<=0)goto err_out; ci->residue_param=_ogg_malloc(sizeof(*ci->residue_param)*ci->residues); for(i=0;i<ci->residues;i++) if(res_unpack(ci->residue_param+i,vi,opb))goto err_out; /* map backend settings */ ci->maps=oggpack_read(opb,6)+1; + if(ci->maps<=0)goto err_out; ci->map_param=_ogg_malloc(sizeof(*ci->map_param)*ci->maps); for(i=0;i<ci->maps;i++){ if(oggpack_read(opb,16)!=0)goto err_out; if(mapping_info_unpack(ci->map_param+i,vi,opb))goto err_out; } - + /* mode settings */ ci->modes=oggpack_read(opb,6)+1; + if(ci->modes<=0)goto err_out; ci->mode_param= (vorbis_info_mode *)_ogg_malloc(ci->modes*sizeof(*ci->mode_param)); for(i=0;i<ci->modes;i++){ @@ -277,8 +282,9 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ if(oggpack_read(opb,16))goto err_out; ci->mode_param[i].mapping=(unsigned char)oggpack_read(opb,8); if(ci->mode_param[i].mapping>=ci->maps)goto err_out; + if(ci->mode_param[i].mapping<0)goto err_out; } - + if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ return(0); @@ -294,7 +300,7 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ int vorbis_dsp_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ oggpack_buffer opb; - + if(op){ oggpack_readinit(&opb,op->packet); @@ -49,17 +49,23 @@ static int ilog(unsigned int v){ /* also responsible for range checking */ int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi, oggpack_buffer *opb){ - int i; + int i,b; codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; memset(info,0,sizeof(*info)); - if(oggpack_read(opb,1)) + b=oggpack_read(opb,1); + if(b<0)goto err_out; + if(b){ info->submaps=oggpack_read(opb,4)+1; - else + if(info->submaps<=0)goto err_out; + }else info->submaps=1; - if(oggpack_read(opb,1)){ + b=oggpack_read(opb,1); + if(b<0)goto err_out; + if(b){ info->coupling_steps=oggpack_read(opb,8)+1; + if(info->coupling_steps<=0)goto err_out; info->coupling= _ogg_malloc(info->coupling_steps*sizeof(*info->coupling)); @@ -76,14 +82,14 @@ int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi, } - if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */ + if(oggpack_read(opb,2)!=0)goto err_out; /* 2,3:reserved */ if(info->submaps>1){ info->chmuxlist=_ogg_malloc(sizeof(*info->chmuxlist)*vi->channels); if (!info->chmuxlist) goto err_out; for(i=0;i<vi->channels;i++){ info->chmuxlist[i]=(unsigned char)oggpack_read(opb,4); - if(info->chmuxlist[i]>=info->submaps)goto err_out; + if(info->chmuxlist[i]>=info->submaps || info->chmuxlist[i]<0)goto err_out; } } @@ -92,9 +98,10 @@ int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi, for(i=0;i<info->submaps;i++){ int temp=oggpack_read(opb,8); info->submaplist[i].floor=(char)oggpack_read(opb,8); - if(info->submaplist[i].floor>=ci->floors)goto err_out; + if(info->submaplist[i].floor>=ci->floors || info->submaplist[i].floor<0)goto err_out; info->submaplist[i].residue=(char)oggpack_read(opb,8); - if(info->submaplist[i].residue>=ci->residues)goto err_out; + if(info->submaplist[i].residue>=ci->residues || info->submaplist[i].residue<0) + goto err_out; } return 0; |