Bug 1339612 - Update libogg to version 1.3.2. r=rillian, a=jcristau
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 15 Feb 2017 19:39:47 -0500
changeset 378526 9ec7bed2e1e00ea8de27f16642425719d74bf4bf
parent 378525 cd49d673aad3f925338ae31a0d8762edfbf8c0ff
child 378527 197dde7656f8d4b8f136233a664891ba8d0b150a
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrillian, jcristau
bugs1339612
milestone53.0a2
Bug 1339612 - Update libogg to version 1.3.2. r=rillian, a=jcristau
media/libogg/CHANGES
media/libogg/README_MOZILLA
media/libogg/include/ogg/os_types.h
media/libogg/src/ogg_bitwise.c
media/libogg/src/ogg_framing.c
--- a/media/libogg/CHANGES
+++ b/media/libogg/CHANGES
@@ -1,8 +1,19 @@
+Version 1.3.2 (2014 May 27)
+
+ * Fix an bug in oggpack_writecopy().
+
+Version 1.3.1 (2013 May 12)
+
+* Guard against very large packets.
+* Respect the configure --docdir override.
+* Documentation fixes.
+* More Windows build fixes.
+
 Version 1.3.0 (2011 August 4)
 
 * Add ogg_stream_flush_fill() call
   This produces longer packets on flush, similar to
   what ogg_stream_pageout_fill() does for single pages.
 * Windows build fixes
 
 Version 1.2.2 (2010 December 07)
--- a/media/libogg/README_MOZILLA
+++ b/media/libogg/README_MOZILLA
@@ -1,8 +1,8 @@
-The source from this directory was copied from the libogg subversion
-repository using the update.sh script.
+Version: 1.3.2
 
-The svn revision number used was r17287.
+The source from this directory was extracted from the official source
+package downloaded from xiph.org and copied using the update.sh script.
 
 The int-types.patch address a bug that config_types.h generated from
 Linux platform can't be used on OpenSolaris directly see Mozilla bug
 449754
--- a/media/libogg/include/ogg/os_types.h
+++ b/media/libogg/include/ogg/os_types.h
@@ -6,17 +6,17 @@
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
  function: #ifdef jail to whip a few platforms into the UNIX ideal.
- last mod: $Id: os_types.h 17712 2010-12-03 17:10:02Z xiphmont $
+ last mod: $Id: os_types.h 19098 2014-02-26 19:06:45Z giles $
 
  ********************************************************************/
 #ifndef _OS_TYPES_H
 #define _OS_TYPES_H
 
 #include <stddef.h>
 
 /* We indirect mallocs through settable-at-runtime functions to accommodate
@@ -40,17 +40,17 @@ extern ogg_free_function_type *ogg_free_
 }
 #endif
 
 #define _ogg_malloc ogg_malloc_func
 #define _ogg_calloc ogg_calloc_func
 #define _ogg_realloc ogg_realloc_func
 #define _ogg_free ogg_free_func
 
-#if defined(_WIN32) 
+#if defined(_WIN32)
 
 #  if defined(__CYGWIN__)
 #    include <stdint.h>
      typedef int16_t ogg_int16_t;
      typedef uint16_t ogg_uint16_t;
      typedef int32_t ogg_int32_t;
      typedef uint32_t ogg_uint32_t;
      typedef int64_t ogg_int64_t;
--- a/media/libogg/src/ogg_bitwise.c
+++ b/media/libogg/src/ogg_bitwise.c
@@ -1,22 +1,22 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE.              *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2014             *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
   function: packing variable sized words into an octet stream
-  last mod: $Id: bitwise.c 18051 2011-08-04 17:56:39Z giles $
+  last mod: $Id: bitwise.c 19149 2014-05-27 16:26:23Z giles $
 
  ********************************************************************/
 
 /* We're 'LSb' endian; if we write a word but read individual bits,
    then we'll read the lsb first */
 
 #include <string.h>
 #include <stdlib.h>
@@ -182,42 +182,46 @@ static void oggpack_writecopy_helper(ogg
                                      long bits,
                                      void (*w)(oggpack_buffer *,
                                                unsigned long,
                                                int),
                                      int msb){
   unsigned char *ptr=(unsigned char *)source;
 
   long bytes=bits/8;
+  long pbytes=(b->endbit+bits)/8;
   bits-=bytes*8;
 
+  /* expand storage up-front */
+  if(b->endbyte+pbytes>=b->storage){
+    void *ret;
+    if(!b->ptr) goto err;
+    if(b->storage>b->endbyte+pbytes+BUFFER_INCREMENT) goto err;
+    b->storage=b->endbyte+pbytes+BUFFER_INCREMENT;
+    ret=_ogg_realloc(b->buffer,b->storage);
+    if(!ret) goto err;
+    b->buffer=ret;
+    b->ptr=b->buffer+b->endbyte;
+  }
+
+  /* copy whole octets */
   if(b->endbit){
     int i;
     /* unaligned copy.  Do it the hard way. */
     for(i=0;i<bytes;i++)
       w(b,(unsigned long)(ptr[i]),8);
   }else{
     /* aligned block copy */
-    if(b->endbyte+bytes+1>=b->storage){
-      void *ret;
-      if(!b->ptr) goto err;
-      if(b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err;
-      b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
-      ret=_ogg_realloc(b->buffer,b->storage);
-      if(!ret) goto err;
-      b->buffer=ret;
-      b->ptr=b->buffer+b->endbyte;
-    }
-
     memmove(b->ptr,source,bytes);
     b->ptr+=bytes;
     b->endbyte+=bytes;
     *b->ptr=0;
+  }
 
-  }
+  /* copy trailing bits */
   if(bits){
     if(msb)
       w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
     else
       w(b,(unsigned long)(ptr[bytes]),bits);
   }
   return;
  err:
@@ -608,19 +612,200 @@ void cliptestB(unsigned long *b,int vals
     }else{
     if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit]))
       report("read incorrect value!\n");
     }
   }
   if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
 }
 
+void copytest(int prefill, int copy){
+  oggpack_buffer source_write;
+  oggpack_buffer dest_write;
+  oggpack_buffer source_read;
+  oggpack_buffer dest_read;
+  unsigned char *source;
+  unsigned char *dest;
+  long source_bytes,dest_bytes;
+  int i;
+
+  oggpack_writeinit(&source_write);
+  oggpack_writeinit(&dest_write);
+
+  for(i=0;i<(prefill+copy+7)/8;i++)
+    oggpack_write(&source_write,(i^0x5a)&0xff,8);
+  source=oggpack_get_buffer(&source_write);
+  source_bytes=oggpack_bytes(&source_write);
+
+  /* prefill */
+  oggpack_writecopy(&dest_write,source,prefill);
+
+  /* check buffers; verify end byte masking */
+  dest=oggpack_get_buffer(&dest_write);
+  dest_bytes=oggpack_bytes(&dest_write);
+  if(dest_bytes!=(prefill+7)/8){
+    fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8);
+    exit(1);
+  }
+  oggpack_readinit(&source_read,source,source_bytes);
+  oggpack_readinit(&dest_read,dest,dest_bytes);
+
+  for(i=0;i<prefill;i+=8){
+    int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8);
+    int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8);
+    if(s!=d){
+      fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
+      exit(1);
+    }
+  }
+  if(prefill<dest_bytes){
+    if(oggpack_read(&dest_read,dest_bytes-prefill)!=0){
+      fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill);
+      exit(1);
+    }
+  }
+
+  /* second copy */
+  oggpack_writecopy(&dest_write,source,copy);
+
+  /* check buffers; verify end byte masking */
+  dest=oggpack_get_buffer(&dest_write);
+  dest_bytes=oggpack_bytes(&dest_write);
+  if(dest_bytes!=(copy+prefill+7)/8){
+    fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8);
+    exit(1);
+  }
+  oggpack_readinit(&source_read,source,source_bytes);
+  oggpack_readinit(&dest_read,dest,dest_bytes);
+
+  for(i=0;i<prefill;i+=8){
+    int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8);
+    int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8);
+    if(s!=d){
+      fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
+      exit(1);
+    }
+  }
+
+  oggpack_readinit(&source_read,source,source_bytes);
+  for(i=0;i<copy;i+=8){
+    int s=oggpack_read(&source_read,copy-i<8?copy-i:8);
+    int d=oggpack_read(&dest_read,copy-i<8?copy-i:8);
+    if(s!=d){
+      fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d);
+      exit(1);
+    }
+  }
+
+  if(copy+prefill<dest_bytes){
+    if(oggpack_read(&dest_read,dest_bytes-copy-prefill)!=0){
+      fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy);
+      exit(1);
+    }
+  }
+
+  oggpack_writeclear(&source_write);
+  oggpack_writeclear(&dest_write);
+
+
+}
+
+void copytestB(int prefill, int copy){
+  oggpack_buffer source_write;
+  oggpack_buffer dest_write;
+  oggpack_buffer source_read;
+  oggpack_buffer dest_read;
+  unsigned char *source;
+  unsigned char *dest;
+  long source_bytes,dest_bytes;
+  int i;
+
+  oggpackB_writeinit(&source_write);
+  oggpackB_writeinit(&dest_write);
+
+  for(i=0;i<(prefill+copy+7)/8;i++)
+    oggpackB_write(&source_write,(i^0x5a)&0xff,8);
+  source=oggpackB_get_buffer(&source_write);
+  source_bytes=oggpackB_bytes(&source_write);
+
+  /* prefill */
+  oggpackB_writecopy(&dest_write,source,prefill);
+
+  /* check buffers; verify end byte masking */
+  dest=oggpackB_get_buffer(&dest_write);
+  dest_bytes=oggpackB_bytes(&dest_write);
+  if(dest_bytes!=(prefill+7)/8){
+    fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8);
+    exit(1);
+  }
+  oggpackB_readinit(&source_read,source,source_bytes);
+  oggpackB_readinit(&dest_read,dest,dest_bytes);
+
+  for(i=0;i<prefill;i+=8){
+    int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8);
+    int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8);
+    if(s!=d){
+      fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
+      exit(1);
+    }
+  }
+  if(prefill<dest_bytes){
+    if(oggpackB_read(&dest_read,dest_bytes-prefill)!=0){
+      fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill);
+      exit(1);
+    }
+  }
+
+  /* second copy */
+  oggpackB_writecopy(&dest_write,source,copy);
+
+  /* check buffers; verify end byte masking */
+  dest=oggpackB_get_buffer(&dest_write);
+  dest_bytes=oggpackB_bytes(&dest_write);
+  if(dest_bytes!=(copy+prefill+7)/8){
+    fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8);
+    exit(1);
+  }
+  oggpackB_readinit(&source_read,source,source_bytes);
+  oggpackB_readinit(&dest_read,dest,dest_bytes);
+
+  for(i=0;i<prefill;i+=8){
+    int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8);
+    int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8);
+    if(s!=d){
+      fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
+      exit(1);
+    }
+  }
+
+  oggpackB_readinit(&source_read,source,source_bytes);
+  for(i=0;i<copy;i+=8){
+    int s=oggpackB_read(&source_read,copy-i<8?copy-i:8);
+    int d=oggpackB_read(&dest_read,copy-i<8?copy-i:8);
+    if(s!=d){
+      fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d);
+      exit(1);
+    }
+  }
+
+  if(copy+prefill<dest_bytes){
+    if(oggpackB_read(&dest_read,dest_bytes-copy-prefill)!=0){
+      fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy);
+      exit(1);
+    }
+  }
+
+  oggpackB_writeclear(&source_write);
+  oggpackB_writeclear(&dest_write);
+
+}
+
 int main(void){
   unsigned char *buffer;
-  long bytes,i;
+  long bytes,i,j;
   static unsigned long testbuffer1[]=
     {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
        567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
   int test1size=43;
 
   static unsigned long testbuffer2[]=
     {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
        1233432,534,5,346435231,14436467,7869299,76326614,167548585,
@@ -756,17 +941,41 @@ int main(void){
       exit(1);
   }
   if(oggpack_look(&r,32)!=-1 ||
      oggpack_look(&r,32)!=-1){
     fprintf(stderr,"failed; read past end without -1.\n");
       exit(1);
   }
   oggpack_writeclear(&o);
-  fprintf(stderr,"ok.\n");
+  fprintf(stderr,"ok.");
+
+  /* this is partly glassbox; we're mostly concerned about the allocation boundaries */
+
+  fprintf(stderr,"\nTesting aligned writecopies (LSb): ");
+  for(i=0;i<71;i++)
+    for(j=0;j<5;j++)
+      copytest(j*8,i);
+  for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
+    for(j=0;j<5;j++)
+      copytest(j*8,i);
+  fprintf(stderr,"ok.      ");
+
+  fprintf(stderr,"\nTesting unaligned writecopies (LSb): ");
+  for(i=0;i<71;i++)
+    for(j=1;j<40;j++)
+      if(j&0x7)
+        copytest(j,i);
+  for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
+    for(j=1;j<40;j++)
+      if(j&0x7)
+        copytest(j,i);
+  
+  fprintf(stderr,"ok.      \n");
+
 
   /********** lazy, cut-n-paste retest with MSb packing ***********/
 
   /* Test read/write together */
   /* Later we test against pregenerated bitstreams */
   oggpackB_writeinit(&o);
 
   fprintf(stderr,"\nSmall preclipped packing (MSb): ");
@@ -841,17 +1050,39 @@ int main(void){
     fprintf(stderr,"failed; read past end without -1.\n");
       exit(1);
   }
   if(oggpackB_look(&r,32)!=-1 ||
      oggpackB_look(&r,32)!=-1){
     fprintf(stderr,"failed; read past end without -1.\n");
       exit(1);
   }
+  fprintf(stderr,"ok.");
   oggpackB_writeclear(&o);
-  fprintf(stderr,"ok.\n\n");
+
+  /* this is partly glassbox; we're mostly concerned about the allocation boundaries */
+
+  fprintf(stderr,"\nTesting aligned writecopies (MSb): ");
+  for(i=0;i<71;i++)
+    for(j=0;j<5;j++)
+      copytestB(j*8,i);
+  for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
+    for(j=0;j<5;j++)
+      copytestB(j*8,i);
+  fprintf(stderr,"ok.      ");
 
+  fprintf(stderr,"\nTesting unaligned writecopies (MSb): ");
+  for(i=0;i<71;i++)
+    for(j=1;j<40;j++)
+      if(j&0x7)
+        copytestB(j,i);
+  for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
+    for(j=1;j<40;j++)
+      if(j&0x7)
+        copytestB(j,i);
+  
+  fprintf(stderr,"ok.      \n\n");
 
   return(0);
 }
 #endif  /* _V_SELFTEST */
 
 #undef BUFFER_INCREMENT
--- a/media/libogg/src/ogg_framing.c
+++ b/media/libogg/src/ogg_framing.c
@@ -7,25 +7,26 @@
  *                                                                  *
  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
  function: code raw packets into framed OggSquish stream and
            decode Ogg streams back into raw packets
- last mod: $Id: framing.c 18052 2011-08-04 17:57:02Z giles $
+ last mod: $Id: framing.c 18758 2013-01-08 16:29:56Z tterribe $
 
  note: The CRC code is directly derived from public domain code by
  Ross Williams (ross@guest.adelaide.edu.au).  See docs/framing.html
  for details.
 
  ********************************************************************/
 
 #include <stdlib.h>
+#include <limits.h>
 #include <string.h>
 #include <ogg/ogg.h>
 
 /* A complete description of Ogg framing exists in docs/framing.html */
 
 int ogg_page_version(const ogg_page *og){
   return((int)(og->header[4]));
 }
@@ -231,49 +232,61 @@ int ogg_stream_destroy(ogg_stream_state 
     _ogg_free(os);
   }
   return(0);
 }
 
 /* Helpers for ogg_stream_encode; this keeps the structure and
    what's happening fairly clear */
 
-static int _os_body_expand(ogg_stream_state *os,int needed){
-  if(os->body_storage<=os->body_fill+needed){
+static int _os_body_expand(ogg_stream_state *os,long needed){
+  if(os->body_storage-needed<=os->body_fill){
+    long body_storage;
     void *ret;
-    ret=_ogg_realloc(os->body_data,(os->body_storage+needed+1024)*
-                     sizeof(*os->body_data));
+    if(os->body_storage>LONG_MAX-needed){
+      ogg_stream_clear(os);
+      return -1;
+    }
+    body_storage=os->body_storage+needed;
+    if(body_storage<LONG_MAX-1024)body_storage+=1024;
+    ret=_ogg_realloc(os->body_data,body_storage*sizeof(*os->body_data));
     if(!ret){
       ogg_stream_clear(os);
       return -1;
     }
-    os->body_storage+=(needed+1024);
+    os->body_storage=body_storage;
     os->body_data=ret;
   }
   return 0;
 }
 
-static int _os_lacing_expand(ogg_stream_state *os,int needed){
-  if(os->lacing_storage<=os->lacing_fill+needed){
+static int _os_lacing_expand(ogg_stream_state *os,long needed){
+  if(os->lacing_storage-needed<=os->lacing_fill){
+    long lacing_storage;
     void *ret;
-    ret=_ogg_realloc(os->lacing_vals,(os->lacing_storage+needed+32)*
-                     sizeof(*os->lacing_vals));
+    if(os->lacing_storage>LONG_MAX-needed){
+      ogg_stream_clear(os);
+      return -1;
+    }
+    lacing_storage=os->lacing_storage+needed;
+    if(lacing_storage<LONG_MAX-32)lacing_storage+=32;
+    ret=_ogg_realloc(os->lacing_vals,lacing_storage*sizeof(*os->lacing_vals));
     if(!ret){
       ogg_stream_clear(os);
       return -1;
     }
     os->lacing_vals=ret;
-    ret=_ogg_realloc(os->granule_vals,(os->lacing_storage+needed+32)*
+    ret=_ogg_realloc(os->granule_vals,lacing_storage*
                      sizeof(*os->granule_vals));
     if(!ret){
       ogg_stream_clear(os);
       return -1;
     }
     os->granule_vals=ret;
-    os->lacing_storage+=(needed+32);
+    os->lacing_storage=lacing_storage;
   }
   return 0;
 }
 
 /* checksum the page */
 /* Direct table CRC; note that this will be faster in the future if we
    perform the checksum simultaneously with other copies */
 
@@ -299,22 +312,27 @@ void ogg_page_checksum_set(ogg_page *og)
     og->header[25]=(unsigned char)((crc_reg>>24)&0xff);
   }
 }
 
 /* submit data to the internal buffer of the framing engine */
 int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
                        long e_o_s, ogg_int64_t granulepos){
 
-  int bytes = 0, lacing_vals, i;
+  long bytes = 0, lacing_vals;
+  int i;
 
   if(ogg_stream_check(os)) return -1;
   if(!iov) return 0;
 
-  for (i = 0; i < count; ++i) bytes += (int)iov[i].iov_len;
+  for (i = 0; i < count; ++i){
+    if(iov[i].iov_len>LONG_MAX) return -1;
+    if(bytes>LONG_MAX-(long)iov[i].iov_len) return -1;
+    bytes += (long)iov[i].iov_len;
+  }
   lacing_vals=bytes/255+1;
 
   if(os->body_returned){
     /* advance packet data according to the body_returned pointer. We
        had to keep it around to return a pointer into the buffer last
        call */
 
     os->body_fill-=os->body_returned;