Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions doc/dox_comments/header_files/compress.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,22 +121,24 @@ int wc_Compress_ex(byte* out, word32 outSz, const byte* in, word32 inSz,

\return On successfully decompressing the input data, returns the
number of bytes stored in the output buffer
\return COMPRESS_INIT_E Returned if there is an error initializing
\return BAD_FUNC_ARG Returned if out or in is NULL
\return DECOMPRESS_INIT_E Returned if there is an error initializing
the stream for decompression
\return COMPRESS_E Returned if an error occurs during decompression
\return DECOMPRESS_E Returned if an error occurs during decompression

\param out pointer to the output buffer in which to store the
decompressed data
\param outSz size available in the output buffer for storage
\param in pointer to the buffer containing the message to decompress
\param inSz size of the input message to decompress
\param windowBits the base two logarithm of the window size (8..15)
\param windowBits format flag OR'd with the default window bits:
0 for zlib-wrapped data, LIBZ_WINBITS_GZIP for gzip-wrapped data

_Example_
\code
byte compressed[] = { // initialize compressed message };
byte decompressed[MAX_MESSAGE_SIZE];
int windowBits = 15;
int windowBits = 0;

int ret = wc_DeCompress_ex(decompressed, sizeof(decompressed),
compressed, sizeof(compressed),
Expand All @@ -160,29 +162,35 @@ int wc_DeCompress_ex(byte* out, word32 outSz, const byte* in, word32 inSz,

\return On successfully decompressing the input data, returns the
number of bytes stored in the output buffer
\return COMPRESS_INIT_E Returned if there is an error initializing
\return BAD_FUNC_ARG Returned if out or in is NULL, inSz is 0 or too
large, or max is 0 or a negative value other than -1
\return DECOMPRESS_INIT_E Returned if there is an error initializing
the stream for decompression
\return COMPRESS_E Returned if an error occurs during decompression
\return DECOMPRESS_E Returned if an error occurs during decompression,
including when the output would exceed the limit set by max
\return MEMORY_E Returned if memory allocation fails

\param out pointer to pointer that will be set to the allocated
output buffer
\param max maximum size to allocate for output buffer
\param max maximum decompression ratio: the output buffer is limited
to inSz * max bytes (capped at INT_MAX). Use -1 for no limit (up to
INT_MAX bytes). 0 and other negative values are rejected.
\param memoryType type of memory to allocate (DYNAMIC_TYPE_TMP_BUFFER)
\param in pointer to the buffer containing the message to decompress
\param inSz size of the input message to decompress
\param windowBits the base two logarithm of the window size (8..15)
\param windowBits format flag OR'd with the default window bits:
0 for zlib-wrapped data, LIBZ_WINBITS_GZIP for gzip-wrapped data
\param heap heap hint for memory allocation (can be NULL)

_Example_
\code
byte compressed[] = { // initialize compressed message };
byte* decompressed = NULL;
int max = 1024 * 1024; // 1MB max
int max = 4; // allow output up to 4 times the input size

int ret = wc_DeCompressDynamic(&decompressed, max,
DYNAMIC_TYPE_TMP_BUFFER, compressed,
sizeof(compressed), 15, NULL);
sizeof(compressed), 0, NULL);
if (ret < 0) {
// error decompressing data
}
Expand Down
58 changes: 58 additions & 0 deletions tests/api/test_compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,64 @@
#define TEST_TLS_COMPRESSION
#endif

/*
* testing wc_DeCompressDynamic maxSz handling: -1 is unlimited, values >= 1
* are a multiplier on inSz, and 0 / other negative values are rejected
*/
int test_wc_DeCompressDynamic_maxSz(void)
{
EXPECT_DECLS;
#ifdef HAVE_LIBZ
byte plain[4096];
byte comp[sizeof(plain) + 64];
byte* out = NULL;
int compSz = 0;

/* Highly compressible input so the output is far larger than inSz. */
XMEMSET(plain, 0, sizeof(plain));
ExpectIntGT(compSz = wc_Compress(comp, (word32)sizeof(comp), plain,
(word32)sizeof(plain), 0), 0);

/* 0 and negative values other than -1 are invalid. */
ExpectIntEQ(wc_DeCompressDynamic(&out, 0, DYNAMIC_TYPE_TMP_BUFFER,
comp, (word32)compSz, 0, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_DeCompressDynamic(&out, -2, DYNAMIC_TYPE_TMP_BUFFER,
comp, (word32)compSz, 0, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_DeCompressDynamic(&out, INT_MIN, DYNAMIC_TYPE_TMP_BUFFER,
comp, (word32)compSz, 0, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectNull(out);

/* -1: no limit, decompresses fully. */
ExpectIntEQ(wc_DeCompressDynamic(&out, -1, DYNAMIC_TYPE_TMP_BUFFER,
comp, (word32)compSz, 0, NULL), (int)sizeof(plain));
ExpectNotNull(out);
if (out != NULL) {
ExpectIntEQ(XMEMCMP(out, plain, sizeof(plain)), 0);
XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
out = NULL;
}

/* 1 and 2: limit (inSz * maxSz) is far below the output size. */
ExpectIntEQ(wc_DeCompressDynamic(&out, 1, DYNAMIC_TYPE_TMP_BUFFER,
comp, (word32)compSz, 0, NULL), WC_NO_ERR_TRACE(DECOMPRESS_E));
ExpectIntEQ(wc_DeCompressDynamic(&out, 2, DYNAMIC_TYPE_TMP_BUFFER,
comp, (word32)compSz, 0, NULL), WC_NO_ERR_TRACE(DECOMPRESS_E));
ExpectNull(out);

/* Large enough multiplier: decompresses fully. */
ExpectIntEQ(wc_DeCompressDynamic(&out, (int)sizeof(plain),
DYNAMIC_TYPE_TMP_BUFFER, comp, (word32)compSz, 0, NULL),
(int)sizeof(plain));
ExpectNotNull(out);
if (out != NULL) {
ExpectIntEQ(XMEMCMP(out, plain, sizeof(plain)), 0);
XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
out = NULL;
}
#endif
return EXPECT_RESULT();
} /* END test_wc_DeCompressDynamic_maxSz */

/*
* MC/DC decision coverage for the zlib wrapper (wolfcrypt/src/compress.c).
* compress_test() in testwolfcrypt exercises the round trips; this drives the
Expand Down
2 changes: 2 additions & 0 deletions tests/api/test_compress.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <tests/api/api_decl.h>

int test_wc_DeCompressDynamic_maxSz(void);
int test_wc_CompressDecisionCoverage(void);
int test_wolfSSL_tls_compression(void);
int test_wolfSSL_tls_compression_multi_record(void);
Expand All @@ -37,6 +38,7 @@ int test_wolfSSL_tls_compression_output_size(void);
int test_wolfSSL_dtls_compression_off(void);

#define TEST_COMPRESS_DECLS \
TEST_DECL_GROUP("compress", test_wc_DeCompressDynamic_maxSz), \
TEST_DECL_GROUP("compress", test_wc_CompressDecisionCoverage), \
TEST_DECL_GROUP("compress", test_wolfSSL_tls_compression), \
TEST_DECL_GROUP("compress", test_wolfSSL_tls_compression_multi_record), \
Expand Down
6 changes: 6 additions & 0 deletions wolfcrypt/src/compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,12 @@ int wc_DeCompressDynamic(byte** out, int maxSz, int memoryType,
if (inSz == 0 || inSz > (word32)(INT_MAX / 2)) {
return BAD_FUNC_ARG;
}

/* maxSz is a multiplier on inSz; -1 means no limit. 0 and other
* negative values are rejected. */
if (maxSz != -1 && maxSz <= 0) {
return BAD_FUNC_ARG;
}
i = (maxSz == 1)? 1 : 2; /* start with output buffer twice the size of input
* unless max was set to 1 */

Expand Down
Loading