mirror of
https://github.com/google/brotli.git
synced 2025-01-05 22:41:08 +00:00
Merge pull request #13 from szabadka/master
Fix potential output buffer overflow in encoder.
This commit is contained in:
commit
37aa5e05c0
@ -17,6 +17,8 @@
|
||||
#ifndef BROTLI_ENC_DICTIONARY_H_
|
||||
#define BROTLI_ENC_DICTIONARY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint8_t kBrotliDictionary[] = {
|
||||
0x74, 0x69, 0x6d, 0x65, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x66, 0x65, 0x6c,
|
||||
0x65, 0x66, 0x74, 0x62, 0x61, 0x63, 0x6b, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x61,
|
||||
|
@ -481,7 +481,7 @@ void BrotliCompressor::WriteStreamHeader() {
|
||||
}
|
||||
}
|
||||
|
||||
void BrotliCompressor::WriteMetaBlock(const size_t input_size,
|
||||
bool BrotliCompressor::WriteMetaBlock(const size_t input_size,
|
||||
const uint8_t* input_buffer,
|
||||
const bool is_last,
|
||||
size_t* encoded_size,
|
||||
@ -543,6 +543,9 @@ void BrotliCompressor::WriteMetaBlock(const size_t input_size,
|
||||
storage_[storage_ix_ >> 3] &= (1 << (storage_ix_ & 7)) - 1;
|
||||
EncodeMetaBlockLength(input_size, false, true, &storage_ix_, storage_);
|
||||
size_t hdr_size = (storage_ix_ + 7) >> 3;
|
||||
if ((hdr_size + input_size + (is_last ? 1 : 0)) > *encoded_size) {
|
||||
return false;
|
||||
}
|
||||
memcpy(encoded_buffer, storage_, hdr_size);
|
||||
memcpy(encoded_buffer + hdr_size, input_buffer, input_size);
|
||||
*encoded_size = hdr_size + input_size;
|
||||
@ -553,6 +556,9 @@ void BrotliCompressor::WriteMetaBlock(const size_t input_size,
|
||||
storage_ix_ = 0;
|
||||
storage_[0] = 0;
|
||||
} else {
|
||||
if (output_size > *encoded_size) {
|
||||
return false;
|
||||
}
|
||||
memcpy(encoded_buffer, storage_, output_size);
|
||||
*encoded_size = output_size;
|
||||
if (is_last) {
|
||||
@ -563,11 +569,12 @@ void BrotliCompressor::WriteMetaBlock(const size_t input_size,
|
||||
storage_[storage_ix_ >> 3] = storage_[output_size];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BrotliCompressor::FinishStream(
|
||||
bool BrotliCompressor::FinishStream(
|
||||
size_t* encoded_size, uint8_t* encoded_buffer) {
|
||||
WriteMetaBlock(0, NULL, true, encoded_size, encoded_buffer);
|
||||
return WriteMetaBlock(0, NULL, true, encoded_size, encoded_buffer);
|
||||
}
|
||||
|
||||
int BrotliCompressBuffer(BrotliParams params,
|
||||
@ -575,7 +582,10 @@ int BrotliCompressBuffer(BrotliParams params,
|
||||
const uint8_t* input_buffer,
|
||||
size_t* encoded_size,
|
||||
uint8_t* encoded_buffer) {
|
||||
if (input_size == 0) {
|
||||
if (*encoded_size == 0) {
|
||||
// Output buffer needs at least one byte.
|
||||
return 0;
|
||||
} else if (input_size == 0) {
|
||||
encoded_buffer[0] = 6;
|
||||
*encoded_size = 1;
|
||||
return 1;
|
||||
@ -597,8 +607,11 @@ int BrotliCompressBuffer(BrotliParams params,
|
||||
is_last = true;
|
||||
}
|
||||
size_t output_size = max_output_size;
|
||||
compressor.WriteMetaBlock(block_size, input_buffer, is_last,
|
||||
&output_size, &encoded_buffer[*encoded_size]);
|
||||
if (!compressor.WriteMetaBlock(block_size, input_buffer,
|
||||
is_last, &output_size,
|
||||
&encoded_buffer[*encoded_size])) {
|
||||
return 0;
|
||||
}
|
||||
input_buffer += block_size;
|
||||
*encoded_size += output_size;
|
||||
max_output_size -= output_size;
|
||||
|
15
enc/encode.h
15
enc/encode.h
@ -46,18 +46,21 @@ class BrotliCompressor {
|
||||
void WriteStreamHeader();
|
||||
|
||||
// Encodes the data in input_buffer as a meta-block and writes it to
|
||||
// encoded_buffer and sets *encoded_size to the number of bytes that was
|
||||
// written.
|
||||
void WriteMetaBlock(const size_t input_size,
|
||||
// encoded_buffer (*encoded_size should be set to the size of
|
||||
// encoded_buffer) and sets *encoded_size to the number of bytes that
|
||||
// was written. Returns 0 if there was an error and 1 otherwise.
|
||||
bool WriteMetaBlock(const size_t input_size,
|
||||
const uint8_t* input_buffer,
|
||||
const bool is_last,
|
||||
size_t* encoded_size,
|
||||
uint8_t* encoded_buffer);
|
||||
|
||||
// Writes a zero-length meta-block with end-of-input bit set to the
|
||||
// internal output buffer and copies the output buffer to encoded_buffer and
|
||||
// sets *encoded_size to the number of bytes written.
|
||||
void FinishStream(size_t* encoded_size, uint8_t* encoded_buffer);
|
||||
// internal output buffer and copies the output buffer to encoded_buffer
|
||||
// (*encoded_size should be set to the size of encoded_buffer) and sets
|
||||
// *encoded_size to the number of bytes written. Returns false if there was
|
||||
// an error and true otherwise.
|
||||
bool FinishStream(size_t* encoded_size, uint8_t* encoded_buffer);
|
||||
|
||||
private:
|
||||
// Initializes the hasher with the hashes of dictionary words.
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "./port.h"
|
||||
|
||||
namespace brotli {
|
||||
|
@ -17,6 +17,9 @@
|
||||
#ifndef BROTLI_ENC_RINGBUFFER_H_
|
||||
#define BROTLI_ENC_RINGBUFFER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// A RingBuffer(window_bits, tail_bits) contains `1 << window_bits' bytes of
|
||||
// data in a circular manner: writing a byte writes it to
|
||||
// `position() % (1 << window_bits)'. For convenience, the RingBuffer array
|
||||
|
Loading…
Reference in New Issue
Block a user