Bug 1142953 - Update Brotli decompressor to latest upstream revision from GitHub; now at ca29aa22c295daac15baf5d85427ecc7808b515c. r=jdaggett
authorJonathan Kew <jkew@mozilla.com>
Thu, 19 Mar 2015 11:11:28 +0000
changeset 251771 46f600c2366bba5e02566ee85df2a9756d5bf335
parent 251770 c5af0c4863d10b3fc2650d4920624ae8b85fa869
child 251772 eb6141f8f3a342096e162c17381dec1e22426372
push id1154
push usercmanchester@mozilla.com
push dateFri, 20 Mar 2015 01:41:39 +0000
reviewersjdaggett
bugs1142953
milestone39.0a1
Bug 1142953 - Update Brotli decompressor to latest upstream revision from GitHub; now at ca29aa22c295daac15baf5d85427ecc7808b515c. r=jdaggett
modules/brotli/README.mozilla
modules/brotli/dec/Makefile
modules/brotli/dec/README
modules/brotli/dec/bit_reader.h
modules/brotli/dec/decode.c
modules/brotli/dec/decode.h
modules/brotli/dec/safe_malloc.h
modules/brotli/dec/streams.c
modules/brotli/dec/streams.h
modules/brotli/dec/transform.h
modules/brotli/dec/types.h
modules/brotli/update.sh
--- a/modules/brotli/README.mozilla
+++ b/modules/brotli/README.mozilla
@@ -1,17 +1,17 @@
 This is the Brotli data compression library from
-https://code.google.com/p/font-compression-reference/.
+https://github.com/google/brotli.
 
 Currently, we import only the Brotli decoder (the /dec/ subdirectory), not the
 encoder (/enc/ subdirectory).
 
 Upstream code can be viewed at
-  https://code.google.com/p/font-compression-reference/source/browse/#git%2Fbrotli%2Fdec
+  https://github.com/google/brotli/tree/master/dec
 
 and cloned by
-  git clone https://code.google.com/p/font-compression-reference/ 
+  git clone https://github.com/google/brotli
 
 The in-tree copy is updated by running
   sh update.sh
 from within the modules/brotli directory.
 
-Current version: [commit d9a74803fa884559879e3205cfe6f257a2d85519].
+Current version: [commit ca29aa22c295daac15baf5d85427ecc7808b515c].
--- a/modules/brotli/dec/Makefile
+++ b/modules/brotli/dec/Makefile
@@ -1,10 +1,12 @@
 #brotli/dec
 
-include ../../shared.mk
+include ../shared.mk
+
+CPPFLAGS += -Wall
 
 OBJS = bit_reader.o decode.o huffman.o safe_malloc.o streams.o
 
 all : $(OBJS)
 
 clean :
 	rm -f $(OBJS)
deleted file mode 100644
--- a/modules/brotli/dec/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory holds the decoder for brotli compression format.
-
-Brotli is proposed to be used at the byte-compression level in WOFF 2.0 format.
--- a/modules/brotli/dec/bit_reader.h
+++ b/modules/brotli/dec/bit_reader.h
@@ -21,35 +21,46 @@
 #include <string.h>
 #include "./streams.h"
 #include "./types.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
+#if (defined(__x86_64__) || defined(_M_X64))
+/* This should be set to 1 only on little-endian machines. */
+#define BROTLI_USE_64_BITS 1
+#else
+#define BROTLI_USE_64_BITS 0
+#endif
 #define BROTLI_MAX_NUM_BIT_READ   25
 #define BROTLI_READ_SIZE          4096
 #define BROTLI_IBUF_SIZE          (2 * BROTLI_READ_SIZE + 32)
 #define BROTLI_IBUF_MASK          (2 * BROTLI_READ_SIZE - 1)
 
 #define UNALIGNED_COPY64(dst, src) memcpy(dst, src, 8)
+#define UNALIGNED_MOVE64(dst, src) memmove(dst, src, 8)
 
 static const uint32_t kBitMask[BROTLI_MAX_NUM_BIT_READ] = {
   0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767,
   65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215
 };
 
 typedef struct {
   /* Input byte buffer, consist of a ringbuffer and a "slack" region where */
   /* bytes from the start of the ringbuffer are copied. */
   uint8_t buf_[BROTLI_IBUF_SIZE];
   uint8_t*    buf_ptr_;      /* next input will write here */
   BrotliInput input_;        /* input callback */
+#if (BROTLI_USE_64_BITS)
   uint64_t    val_;          /* pre-fetched bits */
+#else
+  uint32_t    val_;          /* pre-fetched bits */
+#endif
   uint32_t    pos_;          /* byte position in stream */
   uint32_t    bit_pos_;      /* current bit-reading position in val_ */
   uint32_t    bit_end_pos_;  /* bit-reading end position from LSB of val_ */
   int         eos_;          /* input stream is finished */
 } BrotliBitReader;
 
 int BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input);
 
@@ -66,21 +77,24 @@ static BROTLI_INLINE void BrotliSetBitPo
   uint32_t n_bits = val - br->bit_pos_;
   const uint32_t bval = (uint32_t)(br->val_ >> br->bit_pos_) & kBitMask[n_bits];
   printf("[BrotliReadBits]  %010d %2d  val: %6x\n",
          (br->pos_ << 3) + br->bit_pos_ - 64, n_bits, bval);
 #endif
   br->bit_pos_ = val;
 }
 
-/* Reload up to 64 bits byte-by-byte */
-static BROTLI_INLINE void ShiftBytes(BrotliBitReader* const br) {
+/*
+ * Reload up to 32 bits byte-by-byte.
+ * This function works on both little and big endian.
+ */
+static BROTLI_INLINE void ShiftBytes32(BrotliBitReader* const br) {
   while (br->bit_pos_ >= 8) {
     br->val_ >>= 8;
-    br->val_ |= ((uint64_t)br->buf_[br->pos_ & BROTLI_IBUF_MASK]) << 56;
+    br->val_ |= ((uint32_t)br->buf_[br->pos_ & BROTLI_IBUF_MASK]) << 24;
     ++br->pos_;
     br->bit_pos_ -= 8;
     br->bit_end_pos_ -= 8;
   }
 }
 
 /* Fills up the input ringbuffer by calling the input callback.
 
@@ -103,68 +117,83 @@ static BROTLI_INLINE int BrotliReadMoreI
     uint8_t* dst = br->buf_ptr_;
     int bytes_read = BrotliRead(br->input_, dst, BROTLI_READ_SIZE);
     if (bytes_read < 0) {
       return 0;
     }
     if (bytes_read < BROTLI_READ_SIZE) {
       br->eos_ = 1;
       /* Store 32 bytes of zero after the stream end. */
-#if (defined(__x86_64__) || defined(_M_X64))
+#if (BROTLI_USE_64_BITS)
       *(uint64_t*)(dst + bytes_read) = 0;
       *(uint64_t*)(dst + bytes_read + 8) = 0;
       *(uint64_t*)(dst + bytes_read + 16) = 0;
       *(uint64_t*)(dst + bytes_read + 24) = 0;
 #else
       memset(dst + bytes_read, 0, 32);
 #endif
     }
     if (dst == br->buf_) {
       /* Copy the head of the ringbuffer to the slack region. */
-#if (defined(__x86_64__) || defined(_M_X64))
+#if (BROTLI_USE_64_BITS)
       UNALIGNED_COPY64(br->buf_ + BROTLI_IBUF_SIZE - 32, br->buf_);
       UNALIGNED_COPY64(br->buf_ + BROTLI_IBUF_SIZE - 24, br->buf_ + 8);
       UNALIGNED_COPY64(br->buf_ + BROTLI_IBUF_SIZE - 16, br->buf_ + 16);
       UNALIGNED_COPY64(br->buf_ + BROTLI_IBUF_SIZE - 8, br->buf_ + 24);
 #else
       memcpy(br->buf_ + (BROTLI_READ_SIZE << 1), br->buf_, 32);
 #endif
       br->buf_ptr_ = br->buf_ + BROTLI_READ_SIZE;
     } else {
       br->buf_ptr_ = br->buf_;
     }
     br->bit_end_pos_ += ((uint32_t)bytes_read << 3);
     return 1;
   }
 }
 
-/* Advances the Read buffer by 5 bytes to make room for reading next 24 bits. */
+/* Guarantees that there are at least 24 bits in the buffer. */
 static BROTLI_INLINE void BrotliFillBitWindow(BrotliBitReader* const br) {
+#if (BROTLI_USE_64_BITS)
   if (br->bit_pos_ >= 40) {
-#if (defined(__x86_64__) || defined(_M_X64))
+    /*
+     * Advances the Read buffer by 5 bytes to make room for reading next
+     * 24 bits.
+     * The expression below needs a little-endian arch to work correctly.
+     * This gives a large speedup for decoding speed.
+     */
     br->val_ >>= 40;
-    /* The expression below needs a little-endian arch to work correctly. */
-    /* This gives a large speedup for decoding speed. */
     br->val_ |= *(const uint64_t*)(
         br->buf_ + (br->pos_ & BROTLI_IBUF_MASK)) << 24;
     br->pos_ += 5;
     br->bit_pos_ -= 40;
     br->bit_end_pos_ -= 40;
+  }
 #else
-    ShiftBytes(br);
+  ShiftBytes32(br);
 #endif
-  }
 }
 
 /* Reads the specified number of bits from Read Buffer. */
 static BROTLI_INLINE uint32_t BrotliReadBits(
     BrotliBitReader* const br, int n_bits) {
   uint32_t val;
+#if (BROTLI_USE_64_BITS)
   BrotliFillBitWindow(br);
   val = (uint32_t)(br->val_ >> br->bit_pos_) & kBitMask[n_bits];
+#else
+  /*
+   * The if statement gives 2-4% speed boost on Canterbury data set with
+   * asm.js/firefox/x86-64.
+   */
+  if ((32 - br->bit_pos_) < ((uint32_t) n_bits)) {
+    BrotliFillBitWindow(br);
+  }
+  val = (br->val_ >> br->bit_pos_) & kBitMask[n_bits];
+#endif
 #ifdef BROTLI_DECODE_DEBUG
   printf("[BrotliReadBits]  %010d %2d  val: %6x\n",
          (br->pos_ << 3) + br->bit_pos_ - 64, n_bits, val);
 #endif
   br->bit_pos_ += (uint32_t)n_bits;
   return val;
 }
 
--- a/modules/brotli/dec/decode.c
+++ b/modules/brotli/dec/decode.c
@@ -45,18 +45,19 @@ static const uint8_t kCodeLengthRepeatCo
 static const int kNumLiteralCodes = 256;
 static const int kNumInsertAndCopyCodes = 704;
 static const int kNumBlockLengthCodes = 26;
 static const int kLiteralContextBits = 6;
 static const int kDistanceContextBits = 2;
 
 #define HUFFMAN_TABLE_BITS      8
 #define HUFFMAN_TABLE_MASK      0xff
-/* This is a rough estimate, not an exact bound. */
-#define HUFFMAN_MAX_TABLE_SIZE  2048
+/* Maximum possible Huffman table size for an alphabet size of 704, max code
+ * length 15 and root table bits 8. */
+#define HUFFMAN_MAX_TABLE_SIZE  1080
 
 #define CODE_LENGTH_CODES 18
 static const uint8_t kCodeLengthCodeOrder[CODE_LENGTH_CODES] = {
   1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 };
 
 #define NUM_DISTANCE_SHORT_CODES 16
 static const int kDistanceShortCodeIndexOffset[NUM_DISTANCE_SHORT_CODES] = {
@@ -526,17 +527,17 @@ static BROTLI_INLINE void DecodeBlockTyp
    dst - src == 1 and len == 1; the last copy will read from byte positions
    [0..7] and write to [4..11], whereas it was only supposed to write to
    position 1. Thus, ten excess bytes.
 */
 static BROTLI_INLINE void IncrementalCopyFastPath(
     uint8_t* dst, const uint8_t* src, int len) {
   if (src < dst) {
     while (dst - src < 8) {
-      UNALIGNED_COPY64(dst, src);
+      UNALIGNED_MOVE64(dst, src);
       len -= (int)(dst - src);
       dst += dst - src;
     }
   }
   while (len > 0) {
     UNALIGNED_COPY64(dst, src);
     src += 8;
     dst += 8;
@@ -547,16 +548,17 @@ static BROTLI_INLINE void IncrementalCop
 int CopyUncompressedBlockToOutput(BrotliOutput output, int len, int pos,
                                   uint8_t* ringbuffer, int ringbuffer_mask,
                                   BrotliBitReader* br) {
   const int rb_size = ringbuffer_mask + 1;
   uint8_t* ringbuffer_end = ringbuffer + rb_size;
   int rb_pos = pos & ringbuffer_mask;
   int br_pos = br->pos_ & BROTLI_IBUF_MASK;
   int nbytes;
+  uint32_t remaining_bits;
 
   /* For short lengths copy byte-by-byte */
   if (len < 8 || br->bit_pos_ + (uint32_t)(len << 3) < br->bit_end_pos_) {
     while (len-- > 0) {
       if (!BrotliReadMoreInput(br)) {
         return 0;
       }
       ringbuffer[rb_pos++]= (uint8_t)BrotliReadBits(br, 8);
@@ -569,18 +571,26 @@ int CopyUncompressedBlockToOutput(Brotli
     }
     return 1;
   }
 
   if (br->bit_end_pos_ < 64) {
     return 0;
   }
 
-  /* Copy remaining 0-8 bytes from br->val_ to ringbuffer. */
-  while (br->bit_pos_ < 64) {
+  /*
+   * Copy remaining 0-4 in 32-bit case or 0-8 bytes in the 64-bit case
+   * from br->val_ to ringbuffer.
+   */
+#if (BROTLI_USE_64_BITS)
+  remaining_bits = 64;
+#else
+  remaining_bits = 32;
+#endif
+  while (br->bit_pos_ < remaining_bits) {
     ringbuffer[rb_pos] = (uint8_t)(br->val_ >> br->bit_pos_);
     br->bit_pos_ += 8;
     ++rb_pos;
     --len;
   }
 
   /* Copy remaining bytes from br->buf_ to ringbuffer. */
   nbytes = (int)(br->bit_end_pos_ - br->bit_pos_) >> 3;
@@ -628,32 +638,72 @@ int CopyUncompressedBlockToOutput(Brotli
   /* Restore the state of the bit reader. */
   BrotliInitBitReader(br, br->input_);
   return 1;
 }
 
 int BrotliDecompressedSize(size_t encoded_size,
                            const uint8_t* encoded_buffer,
                            size_t* decoded_size) {
-  BrotliMemInput memin;
-  BrotliInput input = BrotliInitMemInput(encoded_buffer, encoded_size, &memin);
-  BrotliBitReader br;
-  int meta_block_len;
-  int input_end;
-  int is_uncompressed;
-  if (!BrotliInitBitReader(&br, input)) {
+  int i;
+  uint64_t val = 0;
+  int bit_pos = 0;
+  int is_last;
+  int is_uncompressed = 0;
+  int size_nibbles;
+  int meta_block_len = 0;
+  if (encoded_size == 0) {
     return 0;
   }
-  DecodeWindowBits(&br);
-  DecodeMetaBlockLength(&br, &meta_block_len, &input_end, &is_uncompressed);
-  if (!input_end) {
-    return 0;
+  /* Look at the first 8 bytes, it is enough to decode the length of the first
+     meta-block. */
+  for (i = 0; (size_t)i < encoded_size && i < 8; ++i) {
+    val |= (uint64_t)encoded_buffer[i] << (8 * i);
+  }
+  /* Skip the window bits. */
+  bit_pos += (val & 1) ? 4 : 1;
+  /* Decode the ISLAST bit. */
+  is_last = (val >> bit_pos) & 1;
+  ++bit_pos;
+  if (is_last) {
+    /* Decode the ISEMPTY bit, if it is set to 1, we are done. */
+    if ((val >> bit_pos) & 1) {
+      *decoded_size = 0;
+      return 1;
+    }
+    ++bit_pos;
   }
-  *decoded_size = (size_t)meta_block_len;
-  return 1;
+  /* Decode the length of the first meta-block. */
+  size_nibbles = (int)((val >> bit_pos) & 3) + 4;
+  bit_pos += 2;
+  for (i = 0; i < size_nibbles; ++i) {
+    meta_block_len |= (int)((val >> bit_pos) & 0xf) << (4 * i);
+    bit_pos += 4;
+  }
+  ++meta_block_len;
+  if (is_last) {
+    /* If this meta-block is the only one, we are done. */
+    *decoded_size = (size_t)meta_block_len;
+    return 1;
+  }
+  is_uncompressed = (val >> bit_pos) & 1;
+  ++bit_pos;
+  if (is_uncompressed) {
+    /* If the first meta-block is uncompressed, we skip it and look at the
+       first two bits (ISLAST and ISEMPTY) of the next meta-block, and if
+       both are set to 1, we have a stream with an uncompressed meta-block
+       followed by an empty one, so the decompressed size is the size of the
+       first meta-block. */
+    size_t offset = (size_t)((bit_pos + 7) >> 3) + (size_t)meta_block_len;
+    if (offset < encoded_size && ((encoded_buffer[offset] & 3) == 3)) {
+      *decoded_size = (size_t)meta_block_len;
+      return 1;
+    }
+  }
+  return 0;
 }
 
 int BrotliDecompressBuffer(size_t encoded_size,
                            const uint8_t* encoded_buffer,
                            size_t* decoded_size,
                            uint8_t* decoded_buffer) {
   BrotliMemInput memin;
   BrotliInput in = BrotliInitMemInput(encoded_buffer, encoded_size, &memin);
@@ -940,17 +990,16 @@ int BrotliDecompress(BrotliInput input, 
           goto End;
         }
         if (block_length[2] == 0) {
           DecodeBlockType(num_block_types[2],
                           block_type_trees, 2, block_type, block_type_rb,
                           block_type_rb_index, &br);
           block_length[2] = ReadBlockLength(
               &block_len_trees[2 * HUFFMAN_MAX_TABLE_SIZE], &br);
-          dist_htree_index = (uint8_t)block_type[2];
           dist_context_offset = block_type[2] << kDistanceContextBits;
           dist_context_map_slice = dist_context_map + dist_context_offset;
         }
         --block_length[2];
         context = (uint8_t)(copy_length > 4 ? 3 : copy_length - 2);
         dist_htree_index = dist_context_map_slice[context];
         distance_code = ReadSymbol(hgroup[2].htrees[dist_htree_index], &br);
         if (distance_code >= num_direct_distance_codes) {
--- a/modules/brotli/dec/decode.h
+++ b/modules/brotli/dec/decode.h
@@ -22,17 +22,18 @@
 #include "./types.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
 /* Sets *decoded_size to the decompressed size of the given encoded stream. */
 /* This function only works if the encoded buffer has a single meta block, */
-/* and this meta block must have the "is last" bit set. */
+/* or if it has two meta-blocks, where the first is uncompressed and the */
+/* second is empty. */
 /* Returns 1 on success, 0 on failure. */
 int BrotliDecompressedSize(size_t encoded_size,
                            const uint8_t* encoded_buffer,
                            size_t* decoded_size);
 
 /* Decompresses the data in encoded_buffer into decoded_buffer, and sets */
 /* *decoded_size to the decompressed length. */
 /* Returns 0 if there was either a bit stream error or memory allocation */
--- a/modules/brotli/dec/safe_malloc.h
+++ b/modules/brotli/dec/safe_malloc.h
@@ -10,18 +10,18 @@
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 
    Size-checked memory allocation.
 */
 
-#ifndef BROTLI_UTILS_UTILS_H_
-#define BROTLI_UTILS_UTILS_H_
+#ifndef BROTLI_DEC_SAFE_MALLOC_H_
+#define BROTLI_DEC_SAFE_MALLOC_H_
 
 #include <assert.h>
 
 #include "./types.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
@@ -37,9 +37,9 @@ extern "C" {
    underlying multiply involved.
 */
 void* BrotliSafeMalloc(uint64_t nmemb, size_t size);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }    /* extern "C" */
 #endif
 
-#endif  /* BROTLI_UTILS_UTILS_H_ */
+#endif  /* BROTLI_DEC_SAFE_MALLOC_H_ */
--- a/modules/brotli/dec/streams.c
+++ b/modules/brotli/dec/streams.c
@@ -66,45 +66,58 @@ BrotliOutput BrotliInitMemOutput(uint8_t
   mem_output->length = length;
   mem_output->pos = 0;
   output.cb_ = &BrotliMemOutputFunction;
   output.data_ = mem_output;
   return output;
 }
 
 int BrotliStdinInputFunction(void* data, uint8_t* buf, size_t count) {
+  (void) data; /* Shut up LLVM */
 #ifndef _WIN32
   return (int)read(STDIN_FILENO, buf, count);
 #else
   return -1;
 #endif
 }
 
 BrotliInput BrotliStdinInput() {
   BrotliInput in;
   in.cb_ = BrotliStdinInputFunction;
   in.data_ = NULL;
   return in;
 }
 
 int BrotliStdoutOutputFunction(void* data, const uint8_t* buf, size_t count) {
+  (void) data; /* Shut up LLVM */
 #ifndef _WIN32
   return (int)write(STDOUT_FILENO, buf, count);
 #else
   return -1;
 #endif
 }
 
 BrotliOutput BrotliStdoutOutput() {
   BrotliOutput out;
   out.cb_ = BrotliStdoutOutputFunction;
   out.data_ = NULL;
   return out;
 }
 
+int BrotliFileInputFunction(void* data, uint8_t* buf, size_t count) {
+  return (int)fread(buf, 1, count, (FILE*)data);
+}
+
+BrotliInput BrotliFileInput(FILE* f) {
+  BrotliInput in;
+  in.cb_ = BrotliFileInputFunction;
+  in.data_ = f;
+  return in;
+}
+
 int BrotliFileOutputFunction(void* data, const uint8_t* buf, size_t count) {
   return (int)fwrite(buf, 1, count, (FILE*)data);
 }
 
 BrotliOutput BrotliFileOutput(FILE* f) {
   BrotliOutput out;
   out.cb_ = BrotliFileOutputFunction;
   out.data_ = f;
--- a/modules/brotli/dec/streams.h
+++ b/modules/brotli/dec/streams.h
@@ -87,16 +87,20 @@ BrotliOutput BrotliInitMemOutput(uint8_t
 /* Input callback that reads from standard input. */
 int BrotliStdinInputFunction(void* data, uint8_t* buf, size_t count);
 BrotliInput BrotliStdinInput();
 
 /* Output callback that writes to standard output. */
 int BrotliStdoutOutputFunction(void* data, const uint8_t* buf, size_t count);
 BrotliOutput BrotliStdoutOutput();
 
+/* Input callback that reads from a file. */
+int BrotliFileInputFunction(void* data, uint8_t* buf, size_t count);
+BrotliInput BrotliFileInput(FILE* f);
+
 /* Output callback that writes to a file. */
 int BrotliFileOutputFunction(void* data, const uint8_t* buf, size_t count);
 BrotliOutput BrotliFileOutput(FILE* f);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }    /* extern "C" */
 #endif
 
--- a/modules/brotli/dec/transform.h
+++ b/modules/brotli/dec/transform.h
@@ -177,17 +177,17 @@ static const Transform kTransforms[] = {
      {        " ", kUppercaseAll,   ". "         },
      {        " ", kUppercaseFirst, "=\""        },
      {        " ", kUppercaseAll,   "='"         },
      {        " ", kUppercaseFirst, "='"         },
 };
 
 static const int kNumTransforms = sizeof(kTransforms) / sizeof(kTransforms[0]);
 
-static int ToUpperCase(uint8_t *p, int len) {
+static int ToUpperCase(uint8_t *p) {
   if (p[0] < 0xc0) {
     if (p[0] >= 'a' && p[0] <= 'z') {
       p[0] ^= 32;
     }
     return 1;
   }
   /* An overly simplified uppercasing model for utf-8. */
   if (p[0] < 0xe0) {
@@ -215,20 +215,20 @@ static BROTLI_INLINE int TransformDictio
   word += skip;
   len -= skip;
   if (t <= kOmitLast9) {
     len -= t;
   }
   while (i < len) { dst[idx++] = word[i++]; }
   uppercase = &dst[idx - len];
   if (t == kUppercaseFirst) {
-    ToUpperCase(uppercase, len);
+    ToUpperCase(uppercase);
   } else if (t == kUppercaseAll) {
     while (len > 0) {
-      int step = ToUpperCase(uppercase, len);
+      int step = ToUpperCase(uppercase);
       uppercase += step;
       len -= step;
     }
   }
   while (*suffix) { dst[idx++] = (uint8_t)*suffix++; }
   return idx;
 }
 
--- a/modules/brotli/dec/types.h
+++ b/modules/brotli/dec/types.h
@@ -17,20 +17,21 @@
 
 #ifndef BROTLI_DEC_TYPES_H_
 #define BROTLI_DEC_TYPES_H_
 
 #include <stddef.h>  /* for size_t */
 
 #ifndef _MSC_VER
 #include <inttypes.h>
-#ifdef __STRICT_ANSI__
+#if defined(__cplusplus) || !defined(__STRICT_ANSI__) \
+    || __STDC_VERSION__ >= 199901L
+#define BROTLI_INLINE inline
+#else
 #define BROTLI_INLINE
-#else  /* __STRICT_ANSI__ */
-#define BROTLI_INLINE inline
 #endif
 #else
 typedef signed   char int8_t;
 typedef unsigned char uint8_t;
 typedef signed   short int16_t;
 typedef unsigned short uint16_t;
 typedef signed   int int32_t;
 typedef unsigned int uint32_t;
--- a/modules/brotli/update.sh
+++ b/modules/brotli/update.sh
@@ -1,21 +1,21 @@
 #!/bin/sh
 
 # Script to update the mozilla in-tree copy of the Brotli decompressor.
 # Run this within the /modules/brotli directory of the source tree.
 
 MY_TEMP_DIR=`mktemp -d -t brotli_update` || exit 1
 
-git clone https://code.google.com/p/font-compression-reference/ ${MY_TEMP_DIR}
+git clone https://github.com/google/brotli ${MY_TEMP_DIR}/brotli
 
-COMMIT=`(cd ${MY_TEMP_DIR} && git log | head -n 1)`
+COMMIT=`(cd ${MY_TEMP_DIR}/brotli && git log | head -n 1)`
 perl -p -i -e "s/\[commit [0-9a-f]{40}\]/[${COMMIT}]/" README.mozilla;
 
 rm -rf dec
 mv ${MY_TEMP_DIR}/brotli/dec dec
 rm -rf ${MY_TEMP_DIR}
 hg add dec
 
-echo '###'
-echo '### Updated brotli/dec to $COMMIT.'
-echo '### Remember to verify and commit the changes to source control!'
-echo '###'
+echo "###"
+echo "### Updated brotli/dec to $COMMIT."
+echo "### Remember to verify and commit the changes to source control!"
+echo "###"