summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy B. Terriberry <tterribe@xiph.org>2016-10-03 18:22:16 -0700
committerRalph Giles <giles@mozilla.com>2017-06-16 11:40:19 -0700
commite5b1378996dba3ea82fb35403cb1f0bbff19495c (patch)
treeff37fa72e3177455fa830039cbdb9c4c242fa8c6
parent143caf4023a90c09a5eb685fdd46fb9b9c36b1ee (diff)
downloadlibvorbis-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.c18
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++;