While reviewing a patch to port Tremor r17541, noticed that the
[platform/upstream/libvorbis.git] / lib / codebook.c
index 296bffa..d71525b 100644 (file)
@@ -146,9 +146,9 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
 
 /* unpacks a codebook from the packet buffer into the codebook struct,
    readies the codebook auxiliary structures for decode *************/
-int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
+static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
   long i,j;
-  memset(s,0,sizeof(*s));
+  static_codebook *s=_ogg_calloc(1,sizeof(*s));
   s->allocedp=1;
 
   /* make sure alignment is correct */
@@ -163,12 +163,17 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
 
   /* codeword ordering.... length ordered or unordered? */
   switch((int)oggpack_read(opb,1)){
-  case 0:
+  case 0:{
+    long unused;
+    /* allocated but unused entries? */
+    unused=oggpack_read(opb,1);
+    if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb))
+      goto _eofout;
     /* unordered */
     s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
 
     /* allocated but unused entries? */
-    if(oggpack_read(opb,1)){
+    if(unused){
       /* yes, unused entries */
 
       for(i=0;i<s->entries;i++){
@@ -189,17 +194,23 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
     }
 
     break;
+  }
   case 1:
     /* ordered */
     {
       long length=oggpack_read(opb,5)+1;
+      if(length==0)goto _eofout;
       s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
 
       for(i=0;i<s->entries;){
         long num=oggpack_read(opb,_ilog(s->entries-i));
         if(num==-1)goto _eofout;
+        if(length>32 || num>s->entries-i ||
+           (num>0 && (num-1)>>(length-1)>1)){
+          goto _errout;
+        }
         if(length>32)goto _errout;
-        for(j=0;j<num && i<s->entries;j++,i++)
+        for(j=0;j<num;j++,i++)
           s->lengthlist[i]=length;
         length++;
       }
@@ -207,7 +218,7 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
     break;
   default:
     /* EOF */
-    return(-1);
+    goto _eofout;
   }
 
   /* Do we have a mapping to unpack? */
@@ -237,6 +248,8 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
       }
 
       /* quantized values */
+      if((quantvals*s->q_quant+7>>3)>opb->storage-oggpack_bytes(opb))
+        goto _eofout;
       s->quantlist=_ogg_malloc(sizeof(*s->quantlist)*quantvals);
       for(i=0;i<quantvals;i++)
         s->quantlist[i]=oggpack_read(opb,s->q_quant);
@@ -249,12 +262,12 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
   }
 
   /* all set */
-  return(0);
+  return(s);
 
  _errout:
  _eofout:
-  vorbis_staticbook_clear(s);
-  return(-1);
+  vorbis_staticbook_destroy(s);
+  return(NULL);
 }
 
 /* returns the number of bits ************************************************/