| /////////////////////////////////////////////////////////////////////////////// |
| // |
| /// \file test_stream_flags.c |
| /// \brief Tests Stream Header and Stream tail 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 lzma_stream_flags known_flags; |
| static lzma_stream_flags decoded_flags; |
| static uint8_t buffer[LZMA_STREAM_HEADER_SIZE + LZMA_STREAM_TAIL_SIZE]; |
| static lzma_stream strm = LZMA_STREAM_INIT; |
| |
| |
| static bool |
| validate(void) |
| { |
| if (known_flags.check != decoded_flags.check |
| || known_flags.has_crc32 != decoded_flags.has_crc32 |
| || known_flags.is_multi != decoded_flags.is_multi) |
| return true; |
| |
| return false; |
| } |
| |
| |
| static bool |
| test_header_decoder(size_t expected_size, lzma_ret expected_ret) |
| { |
| memcrap(&decoded_flags, sizeof(decoded_flags)); |
| |
| if (lzma_stream_header_decoder(&strm, &decoded_flags) != LZMA_OK) |
| return true; |
| |
| if (coder_loop(&strm, buffer, expected_size, NULL, 0, |
| expected_ret, LZMA_RUN)) |
| return true; |
| |
| if (expected_ret != LZMA_STREAM_END) |
| return false; |
| |
| return validate(); |
| } |
| |
| |
| static void |
| test_header(void) |
| { |
| memcrap(buffer, sizeof(buffer)); |
| expect(lzma_stream_header_encode(buffer, &known_flags) == LZMA_OK); |
| succeed(test_header_decoder(LZMA_STREAM_HEADER_SIZE, LZMA_STREAM_END)); |
| } |
| |
| |
| static bool |
| test_tail_decoder(size_t expected_size, lzma_ret expected_ret) |
| { |
| memcrap(&decoded_flags, sizeof(decoded_flags)); |
| |
| if (lzma_stream_tail_decoder(&strm, &decoded_flags) != LZMA_OK) |
| return true; |
| |
| if (coder_loop(&strm, buffer, expected_size, NULL, 0, |
| expected_ret, LZMA_RUN)) |
| return true; |
| |
| if (expected_ret == LZMA_STREAM_END && validate()) |
| return true; |
| |
| return false; |
| } |
| |
| |
| static void |
| test_tail(void) |
| { |
| memcrap(buffer, sizeof(buffer)); |
| expect(lzma_stream_tail_encode(buffer, &known_flags) == LZMA_OK); |
| succeed(test_tail_decoder(LZMA_STREAM_TAIL_SIZE, LZMA_STREAM_END)); |
| } |
| |
| |
| static void |
| test_encode_invalid(void) |
| { |
| known_flags.check = LZMA_CHECK_ID_MAX + 1; |
| known_flags.has_crc32 = false; |
| known_flags.is_multi = false; |
| |
| expect(lzma_stream_header_encode(buffer, &known_flags) |
| == LZMA_PROG_ERROR); |
| |
| expect(lzma_stream_tail_encode(buffer, &known_flags) |
| == LZMA_PROG_ERROR); |
| |
| known_flags.check = (lzma_check_type)(-1); |
| |
| expect(lzma_stream_header_encode(buffer, &known_flags) |
| == LZMA_PROG_ERROR); |
| |
| expect(lzma_stream_tail_encode(buffer, &known_flags) |
| == LZMA_PROG_ERROR); |
| } |
| |
| |
| static void |
| test_decode_invalid(void) |
| { |
| known_flags.check = LZMA_CHECK_NONE; |
| known_flags.has_crc32 = false; |
| known_flags.is_multi = false; |
| |
| expect(lzma_stream_header_encode(buffer, &known_flags) == LZMA_OK); |
| |
| // Test 1 (invalid Magic Bytes) |
| buffer[5] ^= 1; |
| succeed(test_header_decoder(6, LZMA_DATA_ERROR)); |
| buffer[5] ^= 1; |
| |
| // Test 2a (valid CRC32) |
| uint32_t crc = lzma_crc32(buffer + 6, 1, 0); |
| for (size_t i = 0; i < 4; ++i) |
| buffer[7 + i] = crc >> (i * 8); |
| succeed(test_header_decoder(LZMA_STREAM_HEADER_SIZE, LZMA_STREAM_END)); |
| |
| // Test 2b (invalid Stream Flags with valid CRC32) |
| buffer[6] ^= 0x20; |
| crc = lzma_crc32(buffer + 6, 1, 0); |
| for (size_t i = 0; i < 4; ++i) |
| buffer[7 + i] = crc >> (i * 8); |
| succeed(test_header_decoder(7, LZMA_HEADER_ERROR)); |
| |
| // Test 3 (invalid CRC32) |
| expect(lzma_stream_header_encode(buffer, &known_flags) == LZMA_OK); |
| buffer[LZMA_STREAM_HEADER_SIZE - 1] ^= 1; |
| succeed(test_header_decoder(LZMA_STREAM_HEADER_SIZE, LZMA_DATA_ERROR)); |
| |
| // Test 4 (invalid Stream Flags) |
| expect(lzma_stream_tail_encode(buffer, &known_flags) == LZMA_OK); |
| buffer[0] ^= 0x40; |
| succeed(test_tail_decoder(1, LZMA_HEADER_ERROR)); |
| buffer[0] ^= 0x40; |
| |
| // Test 5 (invalid Magic Bytes) |
| buffer[2] ^= 1; |
| succeed(test_tail_decoder(3, LZMA_DATA_ERROR)); |
| } |
| |
| |
| int |
| main(void) |
| { |
| lzma_init(); |
| |
| // Valid headers |
| for (lzma_check_type check = LZMA_CHECK_NONE; |
| check <= LZMA_CHECK_ID_MAX; ++check) { |
| for (int has_crc32 = 0; has_crc32 <= 1; ++has_crc32) { |
| for (int is_multi = 0; is_multi <= 1; ++is_multi) { |
| known_flags.check = check; |
| known_flags.has_crc32 = has_crc32; |
| known_flags.is_multi = is_multi; |
| |
| test_header(); |
| test_tail(); |
| } |
| } |
| } |
| |
| // Invalid headers |
| test_encode_invalid(); |
| test_decode_invalid(); |
| |
| lzma_end(&strm); |
| |
| return 0; |
| } |