aboutsummaryrefslogtreecommitdiff
path: root/tests/test_filter_flags.c
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2007-12-09 00:42:33 +0200
committerLasse Collin <lasse.collin@tukaani.org>2007-12-09 00:42:33 +0200
commit5d018dc03549c1ee4958364712fb0c94e1bf2741 (patch)
tree1b211911fb33fddb3f04b77f99e81df23623ffc4 /tests/test_filter_flags.c
downloadxz-5d018dc03549c1ee4958364712fb0c94e1bf2741.tar.xz
Imported to git.
Diffstat (limited to 'tests/test_filter_flags.c')
-rw-r--r--tests/test_filter_flags.c326
1 files changed, 326 insertions, 0 deletions
diff --git a/tests/test_filter_flags.c b/tests/test_filter_flags.c
new file mode 100644
index 00000000..0a16f21a
--- /dev/null
+++ b/tests/test_filter_flags.c
@@ -0,0 +1,326 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file test_filter_flags.c
+/// \brief Tests Filter Flags coders
+//
+// Copyright (C) 2007 Lasse Collin
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "tests.h"
+
+
+static uint8_t buffer[4096];
+static lzma_options_filter known_flags;
+static lzma_options_filter decoded_flags;
+static lzma_stream strm = LZMA_STREAM_INIT;
+
+
+static bool
+encode(uint32_t known_size)
+{
+ memcrap(buffer, sizeof(buffer));
+
+ uint32_t tmp;
+ if (lzma_filter_flags_size(&tmp, &known_flags) != LZMA_OK)
+ return true;
+
+ if (tmp != known_size)
+ return true;
+
+ size_t out_pos = 0;
+ if (lzma_filter_flags_encode(buffer, &out_pos, known_size,
+ &known_flags) != LZMA_OK)
+ return true;
+
+ if (out_pos != known_size)
+ return true;
+
+ return false;
+}
+
+
+static bool
+decode_ret(uint32_t known_size, lzma_ret ret_ok)
+{
+ memcrap(&decoded_flags, sizeof(decoded_flags));
+
+ if (lzma_filter_flags_decoder(&strm, &decoded_flags) != LZMA_OK)
+ return true;
+
+ if (decoder_loop_ret(&strm, buffer, known_size, ret_ok))
+ return true;
+
+ return false;
+}
+
+
+static bool
+decode(uint32_t known_size)
+{
+ if (decode_ret(known_size, LZMA_STREAM_END))
+ return true;
+
+ if (known_flags.id != decoded_flags.id)
+ return true;
+
+ return false;
+}
+
+
+static void
+test_copy(void)
+{
+ // Test 1 (good)
+ known_flags.id = LZMA_FILTER_COPY;
+ known_flags.options = NULL;
+
+ expect(!encode(1));
+ expect(!decode(1));
+ expect(decoded_flags.options == NULL);
+
+ // Test 2 (invalid encoder options)
+ known_flags.options = &known_flags;
+ expect(encode(99));
+
+ // Test 3 (good but unusual Filter Flags field)
+ buffer[0] = 0xE0;
+ buffer[1] = LZMA_FILTER_COPY;
+ expect(!decode(2));
+ expect(decoded_flags.options == NULL);
+
+ // Test 4 (invalid Filter Flags field)
+ buffer[0] = 0xE1;
+ buffer[1] = LZMA_FILTER_COPY;
+ buffer[2] = 0;
+ expect(!decode_ret(3, LZMA_HEADER_ERROR));
+
+ // Test 5 (good but weird Filter Flags field)
+ buffer[0] = 0xFF;
+ buffer[1] = LZMA_FILTER_COPY;
+ buffer[2] = 0;
+ expect(!decode(3));
+ expect(decoded_flags.options == NULL);
+
+ // Test 6 (invalid Filter Flags field)
+ buffer[0] = 0xFF;
+ buffer[1] = LZMA_FILTER_COPY;
+ buffer[2] = 1;
+ buffer[3] = 0;
+ expect(!decode_ret(4, LZMA_HEADER_ERROR));
+}
+
+
+static void
+test_subblock(void)
+{
+ // Test 1
+ known_flags.id = LZMA_FILTER_SUBBLOCK;
+ known_flags.options = NULL;
+
+ expect(!encode(1));
+ expect(!decode(1));
+ expect(decoded_flags.options != NULL);
+ expect(((lzma_options_subblock *)(decoded_flags.options))
+ ->allow_subfilters);
+
+ // Test 2
+ known_flags.options = decoded_flags.options;
+ expect(!encode(1));
+ expect(!decode(1));
+ expect(decoded_flags.options != NULL);
+ expect(((lzma_options_subblock *)(decoded_flags.options))
+ ->allow_subfilters);
+
+ free(decoded_flags.options);
+ free(known_flags.options);
+
+ // Test 3
+ buffer[0] = 0xFF;
+ buffer[1] = LZMA_FILTER_SUBBLOCK;
+ buffer[2] = 1;
+ buffer[3] = 0;
+ expect(!decode_ret(4, LZMA_HEADER_ERROR));
+}
+
+
+static void
+test_simple(void)
+{
+ // Test 1
+ known_flags.id = LZMA_FILTER_X86;
+ known_flags.options = NULL;
+
+ expect(!encode(1));
+ expect(!decode(1));
+ expect(decoded_flags.options == NULL);
+
+ // Test 2
+ lzma_options_simple options;
+ options.start_offset = 0;
+ known_flags.options = &options;
+ expect(!encode(1));
+ expect(!decode(1));
+ expect(decoded_flags.options == NULL);
+
+ // Test 3
+ options.start_offset = 123456;
+ known_flags.options = &options;
+ expect(!encode(6));
+ expect(!decode(6));
+ expect(decoded_flags.options != NULL);
+
+ lzma_options_simple *decoded = decoded_flags.options;
+ expect(decoded->start_offset == options.start_offset);
+
+ free(decoded);
+}
+
+
+static void
+test_delta(void)
+{
+ // Test 1
+ known_flags.id = LZMA_FILTER_DELTA;
+ known_flags.options = NULL;
+ expect(encode(99));
+
+ // Test 2
+ lzma_options_delta options = { 0 };
+ known_flags.options = &options;
+ expect(encode(99));
+
+ // Test 3
+ options.distance = LZMA_DELTA_DISTANCE_MIN;
+ expect(!encode(2));
+ expect(!decode(2));
+ expect(((lzma_options_delta *)(decoded_flags.options))
+ ->distance == options.distance);
+
+ free(decoded_flags.options);
+
+ // Test 4
+ options.distance = LZMA_DELTA_DISTANCE_MAX;
+ expect(!encode(2));
+ expect(!decode(2));
+ expect(((lzma_options_delta *)(decoded_flags.options))
+ ->distance == options.distance);
+
+ free(decoded_flags.options);
+
+ // Test 5
+ options.distance = LZMA_DELTA_DISTANCE_MAX + 1;
+ expect(encode(99));
+}
+
+
+static void
+validate_lzma(void)
+{
+ const lzma_options_lzma *known = known_flags.options;
+ const lzma_options_lzma *decoded = decoded_flags.options;
+
+ expect(known->dictionary_size <= decoded->dictionary_size);
+
+ if (known->dictionary_size == 1)
+ expect(decoded->dictionary_size == 1);
+ else
+ expect(known->dictionary_size + known->dictionary_size / 2
+ > decoded->dictionary_size);
+
+ expect(known->literal_context_bits == decoded->literal_context_bits);
+ expect(known->literal_pos_bits == decoded->literal_pos_bits);
+ expect(known->pos_bits == decoded->pos_bits);
+}
+
+
+static void
+test_lzma(void)
+{
+ // Test 1
+ known_flags.id = LZMA_FILTER_LZMA;
+ known_flags.options = NULL;
+ expect(encode(99));
+
+ // Test 2
+ lzma_options_lzma options = {
+ .dictionary_size = 0,
+ .literal_context_bits = 0,
+ .literal_pos_bits = 0,
+ .pos_bits = 0,
+ .preset_dictionary = NULL,
+ .preset_dictionary_size = 0,
+ .mode = LZMA_MODE_INVALID,
+ .fast_bytes = 0,
+ .match_finder = LZMA_MF_INVALID,
+ .match_finder_cycles = 0,
+ };
+
+ // Test 3 (empty dictionary not allowed)
+ known_flags.options = &options;
+ expect(encode(99));
+
+ // Test 4 (brute-force test some valid dictionary sizes)
+ while (options.dictionary_size != LZMA_DICTIONARY_SIZE_MAX) {
+ if (++options.dictionary_size == 5000)
+ options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX - 5;
+
+ expect(!encode(3));
+ expect(!decode(3));
+ validate_lzma();
+
+ free(decoded_flags.options);
+ }
+
+ // Test 5 (too big dictionary size)
+ options.dictionary_size = LZMA_DICTIONARY_SIZE_MAX + 1;
+ expect(encode(99));
+
+ // Test 6 (brute-force test lc/lp/pb)
+ options.dictionary_size = 1;
+ for (uint32_t lc = LZMA_LITERAL_CONTEXT_BITS_MIN;
+ lc <= LZMA_LITERAL_CONTEXT_BITS_MAX; ++lc) {
+ for (uint32_t lp = LZMA_LITERAL_POS_BITS_MIN;
+ lp <= LZMA_LITERAL_POS_BITS_MAX; ++lp) {
+ for (uint32_t pb = LZMA_POS_BITS_MIN;
+ pb <= LZMA_POS_BITS_MAX; ++pb) {
+ options.literal_context_bits = lc;
+ options.literal_pos_bits = lp;
+ options.pos_bits = pb;
+
+ expect(!encode(3));
+ expect(!decode(3));
+ validate_lzma();
+
+ free(decoded_flags.options);
+ }
+ }
+ }
+}
+
+
+int
+main()
+{
+ lzma_init();
+
+ test_copy();
+ test_subblock();
+ test_simple();
+ test_delta();
+ test_lzma();
+
+ lzma_end(&strm);
+
+ return 0;
+}