aboutsummaryrefslogblamecommitdiff
path: root/tests/test_stream_flags.c
blob: 99e55d5e64ed38fae69813c209527a42467433c5 (plain) (tree)



































































































































































                                                                               
          

























                                                                           
///////////////////////////////////////////////////////////////////////////////
//
/// \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;
}