mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Allow tor_gzip_uncompress to handle multiple concatenated compressed strings.
svn:r4882
This commit is contained in:
parent
445bce75dc
commit
29a6c17d67
@ -30,6 +30,8 @@ const char torgzip_c_id[] = "$Id$";
|
||||
|
||||
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)
|
||||
{
|
||||
@ -53,6 +55,11 @@ method_bits(compress_method_t method)
|
||||
return method == GZIP_METHOD ? 15+16 : 15;
|
||||
}
|
||||
|
||||
/** Given <b>in_len</b> bytes at <b>in</b>, compress them into a newly
|
||||
* allocated buffer, using the method described in <b>method</b>. 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_gzip_compress(char **out, size_t *out_len,
|
||||
const char *in, size_t in_len,
|
||||
@ -138,7 +145,12 @@ tor_gzip_compress(char **out, size_t *out_len,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* DOCDOC -- sets *out to NULL on failure. */
|
||||
/** Given or more zlib-compressed or gzip-compressed strings of total length
|
||||
* <b>in_len</b> bytes at <b>in</b>, uncompress them into a newly allocated
|
||||
* buffer, using the method described in <b>method</b>. Store the uncompressed
|
||||
* string in *<b>out</b>, and its length in *<b>out_len</b>. Return 0 on
|
||||
* success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
tor_gzip_uncompress(char **out, size_t *out_len,
|
||||
const char *in, size_t in_len,
|
||||
@ -186,13 +198,20 @@ tor_gzip_uncompress(char **out, size_t *out_len,
|
||||
switch (inflate(stream, Z_FINISH))
|
||||
{
|
||||
case Z_STREAM_END:
|
||||
goto done;
|
||||
if (stream->avail_in == 0)
|
||||
goto done;
|
||||
if (inflateInit2(stream, method_bits(method)) != Z_OK) {
|
||||
log_fn(LOG_WARN, "Error from inflateInit2: %s",
|
||||
stream->msg?stream->msg:"<no message>");
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case Z_OK:
|
||||
/* In case zlib doesn't work as I think.... */
|
||||
if (stream->avail_out >= stream->avail_in+16)
|
||||
break;
|
||||
case Z_BUF_ERROR:
|
||||
offset = stream->next_out - ((unsigned char*)*out);
|
||||
offset = stream->next_out - (unsigned char*)*out;
|
||||
out_size *= 2;
|
||||
*out = tor_realloc(*out, out_size);
|
||||
stream->next_out = (unsigned char*)(*out + offset);
|
||||
@ -205,7 +224,7 @@ tor_gzip_uncompress(char **out, size_t *out_len,
|
||||
}
|
||||
}
|
||||
done:
|
||||
*out_len = stream->total_out;
|
||||
*out_len = stream->next_out - (unsigned char*)*out;
|
||||
r = inflateEnd(stream);
|
||||
tor_free(stream);
|
||||
if (r != Z_OK) {
|
||||
|
@ -908,7 +908,7 @@ test_gzip(void)
|
||||
char *buf1, *buf2=NULL, *buf3=NULL;
|
||||
size_t len1, len2;
|
||||
|
||||
buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||
buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
|
||||
test_eq(detect_compression_method(buf1, strlen(buf1)), 0);
|
||||
if (is_gzip_supported()) {
|
||||
test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
|
||||
@ -935,6 +935,16 @@ test_gzip(void)
|
||||
test_assert(buf3);
|
||||
test_streq(buf1,buf3);
|
||||
|
||||
tor_free(buf3);
|
||||
buf2 = tor_realloc(buf2, len1*2);
|
||||
memcpy(buf2+len1, buf2, len1);
|
||||
test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2, ZLIB_METHOD));
|
||||
test_eq(len2, (strlen(buf1)+1)*2);
|
||||
test_memeq(buf3,
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
|
||||
(strlen(buf1)+1)*2);
|
||||
|
||||
tor_free(buf2);
|
||||
tor_free(buf3);
|
||||
tor_free(buf1);
|
||||
|
Loading…
Reference in New Issue
Block a user