From f231626244f857bb18b3459f8d6ac143c6f65da6 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Mon, 30 Jan 2017 14:57:02 -0800 Subject: [PATCH] Minor fixes according to comments - Add Facebook copyright notice - Make max size macros more consistent - Fix some unchecked malloc's --- contrib/educational_decoder/README.md | 7 +++--- contrib/educational_decoder/harness.c | 9 +++++++ contrib/educational_decoder/zstd_decompress.c | 24 +++++++++++++++++-- contrib/educational_decoder/zstd_decompress.h | 9 +++++++ 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/contrib/educational_decoder/README.md b/contrib/educational_decoder/README.md index a1f703f6..2e2186e0 100644 --- a/contrib/educational_decoder/README.md +++ b/contrib/educational_decoder/README.md @@ -1,15 +1,16 @@ Educational Decoder =================== -`zstd_decompress.c` is a self-contained implementation of a decoder according -to the Zstandard format specification written in C99. +`zstd_decompress.c` is a self-contained implementation in C99 of a decoder, +according to the [Zstandard format specification]. While it does not implement as many features as the reference decoder, such as the streaming API or content checksums, it is written to be easy to follow and understand, to help understand how the Zstandard format works. It's laid out to match the [format specification], -so it can be used to understand how confusing segments could be implemented. +so it can be used to understand how complex segments could be implemented. It also contains implementations of Huffman and FSE table decoding. +[Zstandard format specification]: https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md [format specification]: https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md `harness.c` provides a simple test harness around the decoder: diff --git a/contrib/educational_decoder/harness.c b/contrib/educational_decoder/harness.c index c44100ff..42424d4b 100644 --- a/contrib/educational_decoder/harness.c +++ b/contrib/educational_decoder/harness.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + #include #include diff --git a/contrib/educational_decoder/zstd_decompress.c b/contrib/educational_decoder/zstd_decompress.c index 7b04c4b2..79fd2685 100644 --- a/contrib/educational_decoder/zstd_decompress.c +++ b/contrib/educational_decoder/zstd_decompress.c @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + /// Zstandard educational decoder implementation /// See https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md @@ -21,10 +30,13 @@ size_t ZSTD_decompress_with_dict(void *dst, size_t dst_len, const void *src, size_t ZSTD_get_decompressed_size(const void *src, size_t src_len); /******* UTILITY MACROS AND TYPES *********************************************/ -#define MAX_WINDOW_SIZE ((size_t)512 << 20) +// Specification recommends supporting at least 8MB. The maximum possible value +// is 1.875TB, but this implementation limits it to 512MB to avoid allocating +// too much memory. +#define MAX_WINDOW_SIZE ((size_t)512 * 1024 * 1024) // Max block size decompressed size is 128 KB and literal blocks must be smaller // than that -#define MAX_LITERALS_SIZE ((size_t)(1024 * 128)) +#define MAX_LITERALS_SIZE ((size_t)128 * 1024) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -2071,6 +2083,10 @@ static void FSE_init_dtable(FSE_dtable *dtable, const i16 *norm_freqs, dtable->num_bits = malloc(size * sizeof(u8)); dtable->new_state_base = malloc(size * sizeof(u16)); + if (!dtable->symbols || !dtable->num_bits || !dtable->new_state_base) { + BAD_ALLOC(); + } + // Used to determine how many bits need to be read for each state, // and where the destination range should start // Needs to be u16 because max value is 2 * max number of symbols, @@ -2207,6 +2223,10 @@ static void FSE_init_dtable_rle(FSE_dtable *dtable, u8 symb) { dtable->num_bits = malloc(sizeof(u8)); dtable->new_state_base = malloc(sizeof(u16)); + if (!dtable->symbols || !dtable->num_bits || !dtable->new_state_base) { + BAD_ALLOC(); + } + // This setup will always have a state of 0, always return symbol `symb`, // and never consume any bits dtable->symbols[0] = symb; diff --git a/contrib/educational_decoder/zstd_decompress.h b/contrib/educational_decoder/zstd_decompress.h index 3e1bc568..6e173672 100644 --- a/contrib/educational_decoder/zstd_decompress.h +++ b/contrib/educational_decoder/zstd_decompress.h @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + size_t ZSTD_decompress(void *dst, size_t dst_len, const void *src, size_t src_len); size_t ZSTD_decompress_with_dict(void *dst, size_t dst_len, const void *src,