summaryrefslogtreecommitdiff
path: root/src/common/compress_zstd.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-04-25 09:41:23 -0400
committerNick Mathewson <nickm@torproject.org>2017-04-25 10:50:50 -0400
commit880fb3e3a9aba21c0b36aa4aa5659432e90eb827 (patch)
treeb742f5773bf54cbf34db66aae503953772e74761 /src/common/compress_zstd.c
parent91dd4a00f7d4891e24187a849933547128aeeb9f (diff)
downloadtor-880fb3e3a9aba21c0b36aa4aa5659432e90eb827.tar.gz
tor-880fb3e3a9aba21c0b36aa4aa5659432e90eb827.zip
Combine all *compress/*uncompress backend function into one
Since we have a streaming API for each compression backend, we don't need a non-streaming API for each: we can build a common non-streaming API at the front-end.
Diffstat (limited to 'src/common/compress_zstd.c')
-rw-r--r--src/common/compress_zstd.c283
1 files changed, 0 insertions, 283 deletions
diff --git a/src/common/compress_zstd.c b/src/common/compress_zstd.c
index 664cce1700..76f2991e3d 100644
--- a/src/common/compress_zstd.c
+++ b/src/common/compress_zstd.c
@@ -85,289 +85,6 @@ tor_zstd_get_header_version_str(void)
#endif
}
-/** Given <b>in_len</b> bytes at <b>in</b>, compress them into a newly
- * allocated buffer, using the Zstandard method. Store the compressed string
- * in *<b>out</b>, and its length in *<b>out_len</b>. Return 0 on success, -1
- * on failure.
- */
-int
-tor_zstd_compress(char **out, size_t *out_len,
- const char *in, size_t in_len,
- compress_method_t method)
-{
-#ifdef HAVE_ZSTD
- ZSTD_CStream *stream = NULL;
- size_t out_size, old_size;
- size_t retval;
-
- tor_assert(out);
- tor_assert(out_len);
- tor_assert(in);
- tor_assert(in_len < UINT_MAX);
- tor_assert(method == ZSTD_METHOD);
-
- *out = NULL;
-
- stream = ZSTD_createCStream();
-
- if (stream == NULL) {
- // Zstandard does not give us any useful error message to why this
- // happened. See https://github.com/facebook/zstd/issues/398
- log_warn(LD_GENERAL, "Error while creating Zstandard stream");
- goto err;
- }
-
- retval = ZSTD_initCStream(stream,
- memory_level(HIGH_COMPRESSION));
-
- if (ZSTD_isError(retval)) {
- log_warn(LD_GENERAL, "Zstandard stream initialization error: %s",
- ZSTD_getErrorName(retval));
- goto err;
- }
-
- // Assume 50% compression and update our buffer in case we need to.
- out_size = in_len / 2;
- if (out_size < 1024)
- out_size = 1024;
-
- *out = tor_malloc(out_size);
- *out_len = 0;
-
- ZSTD_inBuffer input = { in, in_len, 0 };
- ZSTD_outBuffer output = { *out, out_size, 0 };
-
- while (input.pos < input.size) {
- retval = ZSTD_compressStream(stream, &output, &input);
-
- if (ZSTD_isError(retval)) {
- log_warn(LD_GENERAL, "Zstandard stream compression error: %s",
- ZSTD_getErrorName(retval));
- goto err;
- }
-
- if (input.pos < input.size && output.pos == output.size) {
- old_size = out_size;
- out_size *= 2;
-
- if (out_size < old_size) {
- log_warn(LD_GENERAL, "Size overflow in Zstandard compression.");
- goto err;
- }
-
- if (out_size - output.pos > UINT_MAX) {
- log_warn(LD_BUG, "Ran over unsigned int limit of Zstandard while "
- "compressing.");
- goto err;
- }
-
- output.dst = *out = tor_realloc(*out, out_size);
- output.size = out_size;
- }
- }
-
- while (1) {
- retval = ZSTD_endStream(stream, &output);
-
- if (retval == 0)
- break;
-
- if (ZSTD_isError(retval)) {
- log_warn(LD_GENERAL, "Zstandard stream error: %s",
- ZSTD_getErrorName(retval));
- goto err;
- }
-
- if (output.pos == output.size) {
- old_size = out_size;
- out_size *= 2;
-
- if (out_size < old_size) {
- log_warn(LD_GENERAL, "Size overflow in Zstandard compression.");
- goto err;
- }
-
- if (out_size - output.pos > UINT_MAX) {
- log_warn(LD_BUG, "Ran over unsigned int limit of Zstandard while "
- "compressing.");
- goto err;
- }
-
- output.dst = *out = tor_realloc(*out, out_size);
- output.size = out_size;
- }
- }
-
- *out_len = output.pos;
-
- if (tor_compress_is_compression_bomb(*out_len, in_len)) {
- log_warn(LD_BUG, "We compressed something and got an insanely high "
- "compression factor; other Tor instances would think "
- "this is a compression bomb.");
- goto err;
- }
-
- if (stream != NULL) {
- ZSTD_freeCStream(stream);
- }
-
- return 0;
-
- err:
- if (stream != NULL) {
- ZSTD_freeCStream(stream);
- }
-
- tor_free(*out);
- return -1;
-#else // HAVE_ZSTD.
- (void)out;
- (void)out_len;
- (void)in;
- (void)in_len;
- (void)method;
-
- return -1;
-#endif // HAVE_ZSTD.
-}
-
-/** Given a Zstandard compressed string of total length <b>in_len</b> bytes at
- * <b>in</b>, uncompress them into a newly allocated buffer. Store the
- * uncompressed string in *<b>out</b>, and its length in *<b>out_len</b>.
- * Return 0 on success, -1 on failure.
- *
- * If <b>complete_only</b> is true, we consider a truncated input as a failure;
- * otherwise we decompress as much as we can. Warn about truncated or corrupt
- * inputs at <b>protocol_warn_level</b>.
- */
-int
-tor_zstd_uncompress(char **out, size_t *out_len,
- const char *in, size_t in_len,
- compress_method_t method,
- int complete_only,
- int protocol_warn_level)
-{
-#ifdef HAVE_ZSTD
- ZSTD_DStream *stream = NULL;
- size_t retval;
- size_t out_size, old_size;
-
- tor_assert(out);
- tor_assert(out_len);
- tor_assert(in);
- tor_assert(in_len < UINT_MAX);
- tor_assert(method == ZSTD_METHOD);
-
- // FIXME(ahf): Handle this?
- (void)complete_only;
- (void)protocol_warn_level;
-
- *out = NULL;
-
- stream = ZSTD_createDStream();
-
- if (stream == NULL) {
- // Zstandard does not give us any useful error message to why this
- // happened. See https://github.com/facebook/zstd/issues/398
- log_warn(LD_GENERAL, "Error while creating Zstandard stream");
- goto err;
- }
-
- retval = ZSTD_initDStream(stream);
-
- if (ZSTD_isError(retval)) {
- log_warn(LD_GENERAL, "Zstandard stream initialization error: %s",
- ZSTD_getErrorName(retval));
- goto err;
- }
-
- out_size = in_len * 2;
- if (out_size < 1024)
- out_size = 1024;
-
- if (out_size >= SIZE_T_CEILING || out_size > UINT_MAX)
- goto err;
-
- *out = tor_malloc(out_size);
- *out_len = 0;
-
- ZSTD_inBuffer input = { in, in_len, 0 };
- ZSTD_outBuffer output = { *out, out_size, 0 };
-
- while (input.pos < input.size) {
- retval = ZSTD_decompressStream(stream, &output, &input);
-
- if (ZSTD_isError(retval)) {
- log_warn(LD_GENERAL, "Zstandard stream decompression error: %s",
- ZSTD_getErrorName(retval));
- goto err;
- }
-
- if (input.pos < input.size && output.pos == output.size) {
- old_size = out_size;
- out_size *= 2;
-
- if (out_size < old_size) {
- log_warn(LD_GENERAL, "Size overflow in Zstandard compression.");
- goto err;
- }
-
- if (tor_compress_is_compression_bomb(in_len, out_size)) {
- log_warn(LD_GENERAL, "Input looks like a possible Zstandard "
- "compression bomb. Not proceeding.");
- goto err;
- }
-
- if (out_size >= SIZE_T_CEILING) {
- log_warn(LD_BUG, "Hit SIZE_T_CEILING limit while uncompressing "
- "Zstandard data.");
- goto err;
- }
-
- if (out_size - output.pos > UINT_MAX) {
- log_warn(LD_BUG, "Ran over unsigned int limit of Zstandard while "
- "decompressing.");
- goto err;
- }
-
- output.dst = *out = tor_realloc(*out, out_size);
- output.size = out_size;
- }
- }
-
- *out_len = output.pos;
-
- if (stream != NULL) {
- ZSTD_freeDStream(stream);
- }
-
- // NUL-terminate our output.
- if (out_size == *out_len)
- *out = tor_realloc(*out, out_size + 1);
- (*out)[*out_len] = '\0';
-
- return 0;
-
- err:
- if (stream != NULL) {
- ZSTD_freeDStream(stream);
- }
-
- tor_free(*out);
- return -1;
-#else // HAVE_ZSTD.
- (void)out;
- (void)out_len;
- (void)in;
- (void)in_len;
- (void)method;
- (void)complete_only;
- (void)protocol_warn_level;
-
- return -1;
-#endif // HAVE_ZSTD.
-}
-
/** Internal Zstandard state for incremental compression/decompression.
* The body of this struct is not exposed. */
struct tor_zstd_compress_state_t {