From cffec5374b06db0e3052879234e1350dfaf8c246 Mon Sep 17 00:00:00 2001
From: Tim Terriberry <tterribe@xiph.org>
Date: Thu, 14 Oct 2010 01:33:46 +0000
Subject: [PATCH] Port r17029 and r17050 from libvorbis.

Fix leak when aborting out of static_codebook unpack.  Closes #1663.


git-svn-id: https://svn.xiph.org/trunk/Tremor@17530 0101bb08-14d6-0310-b084-bc0e0c8e3800
---
 codebook.c   | 12 ++++++------
 codebook.h   |  3 +--
 info.c       |  4 ++--
 sharedbook.c |  7 +------
 4 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/codebook.c b/codebook.c
index 3381f73..95bd34a 100644
--- a/codebook.c
+++ b/codebook.c
@@ -25,9 +25,9 @@
 
 /* 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));
 
   /* make sure alignment is correct */
   if(oggpack_read(opb,24)!=0x564342)goto _eofout;
@@ -85,7 +85,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? */
@@ -127,12 +127,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); 
 }
 
 /* the 'eliminate the decode tree' optimization actually requires the
diff --git a/codebook.h b/codebook.h
index 07cf812..bb13942 100644
--- a/codebook.h
+++ b/codebook.h
@@ -76,14 +76,13 @@ typedef struct codebook{
 
 } codebook;
 
-extern void vorbis_staticbook_clear(static_codebook *b);
 extern void vorbis_staticbook_destroy(static_codebook *b);
 extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source);
 
 extern void vorbis_book_clear(codebook *b);
 extern long _book_maptype1_quantvals(const static_codebook *b);
 
-extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c);
+extern static_codebook *vorbis_staticbook_unpack(oggpack_buffer *b);
 
 extern long vorbis_book_decode(codebook *book, oggpack_buffer *b);
 extern long vorbis_book_decodevs_add(codebook *book, ogg_int32_t *a, 
diff --git a/info.c b/info.c
index f743d62..3f3308e 100644
--- a/info.c
+++ b/info.c
@@ -233,8 +233,8 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
   ci->books=oggpack_read(opb,8)+1;
   if(ci->books<=0)goto err_out;
   for(i=0;i<ci->books;i++){
-    ci->book_param[i]=(static_codebook *)_ogg_calloc(1,sizeof(*ci->book_param[i]));
-    if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out;
+    ci->book_param[i]=vorbis_staticbook_unpack(opb);
+    if(!ci->book_param[i])goto err_out;
   }
 
   /* time backend settings */
diff --git a/sharedbook.c b/sharedbook.c
index 03c2147..188485e 100644
--- a/sharedbook.c
+++ b/sharedbook.c
@@ -294,15 +294,10 @@ ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap,
   return(NULL);
 }
 
-void vorbis_staticbook_clear(static_codebook *b){
+void vorbis_staticbook_destroy(static_codebook *b){
   if(b->quantlist)_ogg_free(b->quantlist);
   if(b->lengthlist)_ogg_free(b->lengthlist);
   memset(b,0,sizeof(*b));
-
-}
-
-void vorbis_staticbook_destroy(static_codebook *b){
-  vorbis_staticbook_clear(b);
   _ogg_free(b);
 }
 
-- 
GitLab