|
@@ -46,34 +46,16 @@
|
|
|
|
|
|
#include <zlib.h>
|
|
|
|
|
|
+#if defined ZLIB_VERNUM && ZLIB_VERNUM < 0x1200
|
|
|
+#error "We require zlib version 1.2 or later."
|
|
|
+#endif
|
|
|
+
|
|
|
static size_t tor_zlib_state_size_precalc(int inflate,
|
|
|
int windowbits, int memlevel);
|
|
|
|
|
|
/** Total number of bytes allocated for zlib state */
|
|
|
static size_t total_zlib_allocation = 0;
|
|
|
|
|
|
-/** Set to 1 if zlib is a version that supports gzip; set to 0 if it doesn't;
|
|
|
- * set to -1 if we haven't checked yet. */
|
|
|
-static int gzip_is_supported = -1;
|
|
|
-
|
|
|
-/** Return true iff we support gzip-based compression. Otherwise, we need to
|
|
|
- * use zlib. */
|
|
|
-int
|
|
|
-is_gzip_supported(void)
|
|
|
-{
|
|
|
- if (gzip_is_supported >= 0)
|
|
|
- return gzip_is_supported;
|
|
|
-
|
|
|
- if (!strcmpstart(ZLIB_VERSION, "0.") ||
|
|
|
- !strcmpstart(ZLIB_VERSION, "1.0") ||
|
|
|
- !strcmpstart(ZLIB_VERSION, "1.1"))
|
|
|
- gzip_is_supported = 0;
|
|
|
- else
|
|
|
- gzip_is_supported = 1;
|
|
|
-
|
|
|
- return gzip_is_supported;
|
|
|
-}
|
|
|
-
|
|
|
/** Return a string representation of the version of the currently running
|
|
|
* version of zlib. */
|
|
|
const char *
|
|
@@ -165,12 +147,6 @@ tor_gzip_compress(char **out, size_t *out_len,
|
|
|
|
|
|
*out = NULL;
|
|
|
|
|
|
- if (method == GZIP_METHOD && !is_gzip_supported()) {
|
|
|
- /* Old zlib version don't support gzip in deflateInit2 */
|
|
|
- log_warn(LD_BUG, "Gzip not supported with zlib %s", ZLIB_VERSION);
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
stream = tor_malloc_zero(sizeof(struct z_stream_s));
|
|
|
stream->zalloc = Z_NULL;
|
|
|
stream->zfree = Z_NULL;
|
|
@@ -182,9 +158,11 @@ tor_gzip_compress(char **out, size_t *out_len,
|
|
|
method_bits(method, HIGH_COMPRESSION),
|
|
|
get_memlevel(HIGH_COMPRESSION),
|
|
|
Z_DEFAULT_STRATEGY) != Z_OK) {
|
|
|
+ //LCOV_EXCL_START -- we can only provoke failure by giving junk arguments.
|
|
|
log_warn(LD_GENERAL, "Error from deflateInit2: %s",
|
|
|
stream->msg?stream->msg:"<no message>");
|
|
|
goto err;
|
|
|
+ //LCOV_EXCL_STOP
|
|
|
}
|
|
|
|
|
|
/* Guess 50% compression. */
|
|
@@ -237,13 +215,12 @@ tor_gzip_compress(char **out, size_t *out_len,
|
|
|
* the newly unsigned field isn't negative." */
|
|
|
tor_assert(stream->total_out >= 0);
|
|
|
#endif
|
|
|
- if (((size_t)stream->total_out) > out_size + 4097) {
|
|
|
- /* If we're wasting more than 4k, don't. */
|
|
|
- *out = tor_realloc(*out, stream->total_out + 1);
|
|
|
- }
|
|
|
if (deflateEnd(stream)!=Z_OK) {
|
|
|
+ // LCOV_EXCL_START -- unreachable if we handled the zlib structure right
|
|
|
+ tor_assert_nonfatal_unreached();
|
|
|
log_warn(LD_BUG, "Error freeing gzip structures");
|
|
|
goto err;
|
|
|
+ // LCOV_EXCL_STOP
|
|
|
}
|
|
|
tor_free(stream);
|
|
|
|
|
@@ -291,12 +268,6 @@ tor_gzip_uncompress(char **out, size_t *out_len,
|
|
|
tor_assert(in);
|
|
|
tor_assert(in_len < UINT_MAX);
|
|
|
|
|
|
- if (method == GZIP_METHOD && !is_gzip_supported()) {
|
|
|
- /* Old zlib version don't support gzip in inflateInit2 */
|
|
|
- log_warn(LD_BUG, "Gzip not supported with zlib %s", ZLIB_VERSION);
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
*out = NULL;
|
|
|
|
|
|
stream = tor_malloc_zero(sizeof(struct z_stream_s));
|
|
@@ -308,9 +279,11 @@ tor_gzip_uncompress(char **out, size_t *out_len,
|
|
|
|
|
|
if (inflateInit2(stream,
|
|
|
method_bits(method, HIGH_COMPRESSION)) != Z_OK) {
|
|
|
+ // LCOV_EXCL_START -- can only hit this if we give bad inputs.
|
|
|
log_warn(LD_GENERAL, "Error from inflateInit2: %s",
|
|
|
stream->msg?stream->msg:"<no message>");
|
|
|
goto err;
|
|
|
+ // LCOV_EXCL_STOP
|
|
|
}
|
|
|
|
|
|
out_size = in_len * 2; /* guess 50% compression. */
|
|
@@ -451,12 +424,6 @@ tor_zlib_new(int compress, compress_method_t method,
|
|
|
tor_zlib_state_t *out;
|
|
|
int bits, memlevel;
|
|
|
|
|
|
- if (method == GZIP_METHOD && !is_gzip_supported()) {
|
|
|
- /* Old zlib version don't support gzip in inflateInit2 */
|
|
|
- log_warn(LD_BUG, "Gzip not supported with zlib %s", ZLIB_VERSION);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
if (! compress) {
|
|
|
/* use this setting for decompression, since we might have the
|
|
|
* max number of window bits */
|
|
@@ -474,10 +441,10 @@ tor_zlib_new(int compress, compress_method_t method,
|
|
|
if (deflateInit2(&out->stream, Z_BEST_COMPRESSION, Z_DEFLATED,
|
|
|
bits, memlevel,
|
|
|
Z_DEFAULT_STRATEGY) != Z_OK)
|
|
|
- goto err;
|
|
|
+ goto err; // LCOV_EXCL_LINE
|
|
|
} else {
|
|
|
if (inflateInit2(&out->stream, bits) != Z_OK)
|
|
|
- goto err;
|
|
|
+ goto err; // LCOV_EXCL_LINE
|
|
|
}
|
|
|
out->allocation = tor_zlib_state_size_precalc(!compress, bits, memlevel);
|
|
|
|