diff options
author | Timothy B. Terriberry <tterribe@xiph.org> | 2016-10-03 18:22:16 -0700 |
---|---|---|
committer | Ralph Giles <giles@mozilla.com> | 2017-06-16 11:40:19 -0700 |
commit | e5b1378996dba3ea82fb35403cb1f0bbff19495c (patch) | |
tree | ff37fa72e3177455fa830039cbdb9c4c242fa8c6 | |
parent | 143caf4023a90c09a5eb685fdd46fb9b9c36b1ee (diff) | |
download | libvorbis-git-e5b1378996dba3ea82fb35403cb1f0bbff19495c.tar.gz |
Fix signed overflow in _book_maptype1_quantvals().
If b->dims is very large, vals will be 1 and acc1 will overflow a
long.
This causes us to read too many values for this codebook.
Signed-off-by: Monty <xiphmont@xiph.org>
-rw-r--r-- | lib/sharedbook.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/lib/sharedbook.c b/lib/sharedbook.c index 0326def4..f8854f7d 100644 --- a/lib/sharedbook.c +++ b/lib/sharedbook.c @@ -16,6 +16,7 @@ ********************************************************************/ #include <stdlib.h> +#include <limits.h> #include <math.h> #include <string.h> #include <ogg/ogg.h> @@ -158,25 +159,34 @@ ogg_uint32_t *_make_words(char *l,long n,long sparsecount){ that's portable and totally safe against roundoff, but I haven't thought of it. Therefore, we opt on the side of caution */ long _book_maptype1_quantvals(const static_codebook *b){ - long vals=floor(pow((float)b->entries,1.f/b->dim)); + long vals; + if(b->entries<1){ + return(0); + } + vals=floor(pow((float)b->entries,1.f/b->dim)); /* the above *should* be reliable, but we'll not assume that FP is ever reliable when bitstream sync is at stake; verify via integer means that vals really is the greatest value of dim for which vals^b->bim <= b->entries */ /* treat the above as an initial guess */ + if(vals<1){ + vals=1; + } while(1){ long acc=1; long acc1=1; int i; for(i=0;i<b->dim;i++){ + if(b->entries/vals<acc)break; acc*=vals; - acc1*=vals+1; + if(LONG_MAX/(vals+1)<acc1)acc1=LONG_MAX; + else acc1*=vals+1; } - if(acc<=b->entries && acc1>b->entries){ + if(i>=b->dim && acc<=b->entries && acc1>b->entries){ return(vals); }else{ - if(acc>b->entries){ + if(i<b->dim || acc>b->entries){ vals--; }else{ vals++; |