8 #if !HEATSHRINK_DYNAMIC_ALLOC 9 #error Must set HEATSHRINK_DYNAMIC_ALLOC to 1 for dynamic allocation test suite. 16 #ifdef HEATSHRINK_HAS_THEFT 20 static void dump_buf(
char *name, uint8_t *buf, uint16_t count) {
21 for (
int i=0; i<count; i++) {
22 uint8_t c = (uint8_t)buf[i];
23 printf(
"%s %d: 0x%02x ('%c')\n", name, i, c,
isprint(c) ? c :
'.');
39 uint8_t input[] = {
'f',
'o',
'o'};
40 size_t input_size = 0;
52 size_t output_size = 0;
54 output, 256, &output_size));
56 NULL, 256, &output_size));
73 size_t bytes_copied = 0;
76 input, 256, &bytes_copied));
87 size_t bytes_copied = 0;
90 input, 512, &bytes_copied));
100 size_t output_size = 0;
103 output, 512, &output_size);
113 uint8_t output[1024];
115 uint8_t expected[] = { 0x80, 0x40, 0x60, 0x50, 0x38, 0x20 };
117 for (
int i=0; i<5; i++) { input[i] = i; }
135 for (
size_t i=0; i<
sizeof(expected); i++) {
149 uint8_t output[1024];
151 uint8_t expected[] = {0xb0, 0x80, 0x01, 0x80};
153 for (
int i=0; i<5; i++) { input[i] =
'a'; }
171 if (0)
dump_buf(
"output", output, copied);
172 for (
size_t i=0; i<copied; i++)
ASSERT_EQ(expected[i], output[i]);
182 uint8_t input[] = {
'a',
'b',
'c',
'd',
'a',
'b',
'c',
'd'};
183 uint8_t output[1024];
184 uint8_t expected[] = {0xb0, 0xd8, 0xac, 0x76, 0x40, 0x1b };
189 input,
sizeof(input), &copied);
200 if (0)
dump_buf(
"output", output, copied);
202 for (
size_t i=0; i<
sizeof(expected); i++)
ASSERT_EQ(expected[i], output[i]);
209 uint8_t input[] = {
'a',
'b',
'c',
'd',
'a',
'b',
'c',
'd',
'e'};
210 uint8_t output[1024];
211 uint8_t expected[] = {0xb0, 0xd8, 0xac, 0x76, 0x40, 0x1b, 0xb2, 0x80 };
215 input,
sizeof(input), &copied);
226 if (0)
dump_buf(
"output", output, copied);
228 for (
size_t i=0; i<
sizeof(expected); i++)
ASSERT_EQ(expected[i], output[i]);
264 uint8_t input[] = {0,1,2,3,4,5};
280 uint8_t input[] = {0,1,2,3,4,5};
289 uint8_t input[] = {0,1,2,3,4,5};
307 uint8_t input[] = {0,1,2,3,4,5};
359 uint8_t input[] = {0xb3, 0x5b, 0xed, 0xe0 };
380 uint8_t input[] = {0xb3, 0x5b, 0xed, 0xe0, 0x40, 0x80};
383 memset(output, 0,
sizeof(*output));
392 if (0)
dump_buf(
"output", output, out_sz);
407 uint8_t input[] = {0xb0, 0x80, 0x01, 0x80};
409 uint8_t expected[] = {
'a',
'a',
'a',
'a',
'a'};
419 if (0)
dump_buf(
"output", output, out_sz);
421 for (
size_t i=0; i<
sizeof(expected); i++)
ASSERT_EQ(expected[i], output[i]);
428 uint8_t input[] = {0xb3, 0x5b, 0xed, 0xe0, 0x40, 0x80};
447 uint8_t input[] = {0xb3, 0x5b, 0xed, 0xe0, 0x40, 0x80};
450 memset(output, 0,
sizeof(*output));
470 uint8_t input[] = {0xb3, 0x5b, 0xed, 0xe0, 0x40, 0x80};
473 memset(output, 0,
sizeof(*output));
477 for (
int i=0; i<6; i++) {
509 uint8_t input[] = {0xb3, 0x5b, 0xed, 0xe0, 0x40, 0x80};
513 memset(output, 0,
sizeof(*output));
539 uint8_t input[] = {
'a',
'a',
'a',
'a',
'a'};
540 uint8_t output[1024];
544 input,
sizeof(input), &copied);
556 for (
size_t i=0; i<copied; i++)
printf(
"0x%02x, ", output[i]);
567 uint8_t output[1024];
577 for (uint16_t byte = 0; byte < 256; byte++) {
578 for (
int i = 1; i < 512; i++) {
581 memset(output, 0,
sizeof(*output));
643 size_t comp_sz = input_size + (input_size/2) + 4;
644 size_t decomp_sz = input_size + (input_size/2) + 4;
645 uint8_t *comp =
malloc(comp_sz);
646 uint8_t *decomp =
malloc(decomp_sz);
648 if (decomp ==
NULL)
FAILm(
"malloc fail");
650 memset(decomp, 0, decomp_sz);
655 printf(
"\n^^ COMPRESSING\n");
656 dump_buf(
"input", input, input_size);
661 while (sunk < input_size) {
665 if (sunk == input_size) {
677 if (polled >= comp_sz)
FAILm(
"compression should never expand that much");
678 if (sunk == input_size) {
682 if (cfg->
log_lvl > 0)
printf(
"in: %u compressed: %zu ", input_size, polled);
683 size_t compressed_size = polled;
688 printf(
"\n^^ DECOMPRESSING\n");
689 dump_buf(
"comp", comp, compressed_size);
691 while (sunk < compressed_size) {
695 if (sunk == compressed_size) {
702 decomp_sz - polled, &count);
709 if (sunk == compressed_size) {
714 if (polled > input_size) {
715 printf(
"\nExpected %zd, got %zu\n", (
size_t)input_size, polled);
716 FAILm(
"Decompressed data is larger than original input");
720 if (polled != input_size) {
721 FAILm(
"Decompressed length does not match original input length");
725 for (uint32_t i=0; i<input_size; i++) {
726 if (input[i] != decomp[i]) {
727 printf(
"*** mismatch at %d\n", i);
729 for (uint32_t j=0; j<= input_size; j++) {
730 printf(
"in[%d] == 0x%02x ('%c') => out[%d] == 0x%02x ('%c') %c\n",
731 j, input[j],
isprint(input[j]) ? input[j] :
'.',
732 j, decomp[j],
isprint(decomp[j]) ? decomp[j] :
'.',
733 input[j] == decomp[j] ?
' ' :
'X');
747 uint8_t input[] = {
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
748 'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
749 's',
't',
'u',
'v',
'w',
'x',
'y',
'z'};
759 uint8_t input[] = {
'a',
'b',
'c',
'a',
'b',
'c',
'd',
'a',
'b',
760 'c',
'd',
'e',
'a',
'b',
'c',
'd',
'e',
'f',
761 'a',
'b',
'c',
'd',
'e',
'f',
'g',
'a',
'b',
762 'c',
'd',
'e',
'f',
'g',
'h'};
774 uint8_t input[] = {
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
775 'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
776 's',
't',
'u',
'v',
'w',
'x',
'y',
'z'};
782 if (log)
dump_buf(
"input", input,
sizeof(input));
783 for (uint32_t i=0; i<
sizeof(input); i++) {
788 size_t packed_count = 0;
791 packed_count += count;
794 if (log)
dump_buf(
"comp", comp, packed_count);
795 for (uint32_t i=0; i<packed_count; i++) {
801 for (uint32_t i=0; i<
sizeof(input); i++) {
805 if (log)
dump_buf(
"decomp", decomp,
sizeof(input));
806 for (uint32_t i=0; i<
sizeof(input); i++)
ASSERT_EQ(input[i], decomp[i]);
815 uint8_t input[] = {
'a',
'b',
'c',
'a',
'b',
'c',
'd',
'a',
'b',
816 'c',
'd',
'e',
'a',
'b',
'c',
'd',
'e',
'f',
817 'a',
'b',
'c',
'd',
'e',
'f',
'g',
'a',
'b',
818 'c',
'd',
'e',
'f',
'g',
'h'};
824 if (log)
dump_buf(
"input", input,
sizeof(input));
825 for (uint32_t i=0; i<
sizeof(input); i++) {
830 size_t packed_count = 0;
833 packed_count += count;
836 if (log)
dump_buf(
"comp", comp, packed_count);
837 for (uint32_t i=0; i<packed_count; i++) {
843 for (uint32_t i=0; i<
sizeof(input); i++) {
847 if (log)
dump_buf(
"decomp", decomp,
sizeof(input));
848 for (uint32_t i=0; i<
sizeof(input); i++)
ASSERT_EQ(input[i], decomp[i]);
855 uint64_t rn = 9223372036854775783;
856 for (uint32_t i=0; i<
size; i++) {
858 buf[i] = (rn % 26) +
'a';
865 printf(
"\n-- size %u, seed %u, input buf %zu\n",
880 for (uint16_t i=0; i<
size; i++) input[i] =
'a' + (i % 26);
920 uint32_t
size = 64 * 1024;
944 #if __STDC_VERSION__ >= 19901L 945 printf(
"\n\nFuzzing (single-byte sizes):\n");
946 for (uint8_t lsize=3; lsize < 8; lsize++) {
949 for (uint16_t ibs=32; ibs<=8192; ibs <<= 1) {
951 for (uint32_t seed=1; seed<=10; seed++) {
964 printf(
"\nFuzzing (multi-byte sizes):\n");
965 for (uint8_t lsize=6; lsize < 9; lsize++) {
968 for (uint16_t ibs=32; ibs<=8192; ibs <<= 1) {
970 for (uint32_t seed=1; seed<=10; seed++) {
989 int main(
int argc,
char **argv) {
994 #ifdef HEATSHRINK_HAS_THEFT
int main(int argc, char **argv)
size_t decoder_input_buffer_size
TEST encoder_poll_should_reject_nulls(void)
static int compress_and_expand_and_check(uint8_t *input, uint32_t input_size, cfg_info *cfg)
HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, uint8_t *out_buf, size_t out_buf_size, size_t *output_size)
TEST small_input_buffer_should_not_impact_decoder_correctness(void)
TEST decoder_poll_should_reject_null_output_buffer(void)
TEST decoder_should_not_get_stuck_with_finish_yielding_MORE_but_0_bytes_output_from_poll(void)
#define HEATSHRINK_MAX_WINDOW_BITS
TEST decoder_poll_should_expand_short_literal_and_backref_when_fed_input_byte_by_byte(void)
#define HEATSHRINK_MIN_WINDOW_BITS
TEST decoder_poll_should_expand_short_literal(void)
heatshrink_decoder * heatshrink_decoder_alloc(uint16_t input_buffer_size, uint8_t window_sz2, uint8_t lookahead_sz2)
TEST decoder_sink_should_reject_excessively_large_input(void)
TEST pseudorandom_data_should_match(uint32_t size, uint32_t seed, cfg_info *cfg)
TEST encoder_poll_should_detect_repeated_substring_and_preserve_trailing_literal(void)
TEST encoder_poll_should_detect_repeated_substring(void)
TEST encoder_sink_should_accept_partial_input_when_some_will_fit(void)
TEST decoder_sink_should_sink_data_when_preconditions_hold(void)
TEST decoder_finish_should_note_when_done(void)
TEST decoder_sink_should_reject_null_count_pointer(void)
void heatshrink_decoder_free(heatshrink_decoder *hsd)
heatshrink_encoder * heatshrink_encoder_alloc(uint8_t window_sz2, uint8_t lookahead_sz2)
TEST decoder_poll_should_reject_null_output_size_pointer(void)
HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd)
TEST decoder_poll_should_suspend_if_out_of_space_in_output_buffer_during_backref_expansion(void)
TEST decoder_sink_should_reject_null_input_pointer(void)
#define GREATEST_IS_VERBOSE()
static heatshrink_decoder hsd
void heatshrink_encoder_free(heatshrink_encoder *hse)
static void dump_buf(char *name, uint8_t *buf, uint16_t count)
void heatshrink_decoder_reset(heatshrink_decoder *hsd)
TEST encoder_sink_should_accept_input_when_it_will_fit(void)
TEST data_without_duplication_should_match_with_absurdly_tiny_buffers(void)
TEST regression_backreference_counters_should_not_roll_over(void)
HSE_finish_res heatshrink_encoder_finish(heatshrink_encoder *hse)
HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, uint8_t *in_buf, size_t size, size_t *input_size)
TEST decoder_alloc_should_reject_zero_byte_input_buffer(void)
TEST encoder_sink_should_reject_nulls(void)
TEST decoder_poll_should_expand_short_literal_and_backref(void)
HSE_poll_res heatshrink_encoder_poll(heatshrink_encoder *hse, uint8_t *out_buf, size_t out_buf_size, size_t *output_size)
HSE_sink_res heatshrink_encoder_sink(heatshrink_encoder *hse, uint8_t *in_buf, size_t size, size_t *input_size)
TEST encoder_alloc_should_reject_invalid_arguments(void)
static void fill_with_pseudorandom_letters(uint8_t *buf, uint32_t size, uint32_t seed)
TEST decoder_poll_should_suspend_if_out_of_space_in_output_buffer_during_literal_expansion(void)
TEST encoder_should_emit_data_without_repetitions_as_literal_sequence(void)
TEST encoder_finish_should_reject_nulls(void)
TEST decoder_alloc_should_reject_excessively_small_window(void)
TEST data_with_simple_repetition_should_compress_and_decompress_properly(void)
TEST encoder_should_emit_series_of_same_byte_as_literal_then_backref(void)
TEST decoder_poll_should_expand_short_self_overlapping_backref(void)
TEST decoder_sink_should_reject_null_hsd_pointer(void)
TEST encoder_poll_should_indicate_when_no_input_is_provided(void)
TEST regression_index_fail(void)
TEST decoder_finish_should_reject_null_input(void)
#define GREATEST_MAIN_BEGIN()
TEST decoder_poll_should_reject_null_hsd(void)
#define GREATEST_MAIN_END()
TEST decoder_poll_should_return_empty_if_empty(void)
#define HEATSHRINK_MIN_LOOKAHEAD_BITS
TEST data_without_duplication_should_match(void)
static heatshrink_encoder hse
TEST data_with_simple_repetition_should_match_with_absurdly_tiny_buffers(void)