root/tests/test_stream_flags.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. validate
  2. test_header_decoder
  3. test_header
  4. test_footer_decoder
  5. test_footer
  6. test_encode_invalid
  7. test_decode_invalid
  8. main

///////////////////////////////////////////////////////////////////////////////
//
/// \file       test_stream_flags.c
/// \brief      Tests Stream Header and Stream Footer coders
//
//  Author:     Lasse Collin
//
//  This file has been put into the public domain.
//  You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////

#include "tests.h"


static lzma_stream_flags known_flags;
static lzma_stream_flags decoded_flags;
static uint8_t buffer[LZMA_STREAM_HEADER_SIZE];


static bool
validate(void)
{
        // TODO: This could require the specific error type as an argument.
        // We could also test that lzma_stream_flags_compare() gives
        // the correct return values in different situations.
        return lzma_stream_flags_compare(&known_flags, &decoded_flags)
                        != LZMA_OK;
}


static bool
test_header_decoder(lzma_ret expected_ret)
{
        memcrap(&decoded_flags, sizeof(decoded_flags));

        if (lzma_stream_header_decode(&decoded_flags, buffer) != expected_ret)
                return true;

        if (expected_ret != LZMA_OK)
                return false;

        // Header doesn't have Backward Size, so make
        // lzma_stream_flags_compare() ignore it.
        decoded_flags.backward_size = LZMA_VLI_UNKNOWN;
        return validate();
}


static void
test_header(void)
{
        memcrap(buffer, sizeof(buffer));
        expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);
        succeed(test_header_decoder(LZMA_OK));
}


static bool
test_footer_decoder(lzma_ret expected_ret)
{
        memcrap(&decoded_flags, sizeof(decoded_flags));

        if (lzma_stream_footer_decode(&decoded_flags, buffer) != expected_ret)
                return true;

        if (expected_ret != LZMA_OK)
                return false;

        return validate();
}


static void
test_footer(void)
{
        memcrap(buffer, sizeof(buffer));
        expect(lzma_stream_footer_encode(&known_flags, buffer) == LZMA_OK);
        succeed(test_footer_decoder(LZMA_OK));
}


static void
test_encode_invalid(void)
{
        known_flags.check = LZMA_CHECK_ID_MAX + 1;
        known_flags.backward_size = 1024;

        expect(lzma_stream_header_encode(&known_flags, buffer)
                        == LZMA_PROG_ERROR);

        expect(lzma_stream_footer_encode(&known_flags, buffer)
                        == LZMA_PROG_ERROR);

        known_flags.check = (lzma_check)(-1);

        expect(lzma_stream_header_encode(&known_flags, buffer)
                        == LZMA_PROG_ERROR);

        expect(lzma_stream_footer_encode(&known_flags, buffer)
                        == LZMA_PROG_ERROR);

        known_flags.check = LZMA_CHECK_NONE;
        known_flags.backward_size = 0;

        // Header encoder ignores backward_size.
        expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);

        expect(lzma_stream_footer_encode(&known_flags, buffer)
                        == LZMA_PROG_ERROR);

        known_flags.backward_size = LZMA_VLI_MAX;

        expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);

        expect(lzma_stream_footer_encode(&known_flags, buffer)
                        == LZMA_PROG_ERROR);
}


static void
test_decode_invalid(void)
{
        known_flags.check = LZMA_CHECK_NONE;
        known_flags.backward_size = 1024;

        expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);

        // Test 1 (invalid Magic Bytes)
        buffer[5] ^= 1;
        succeed(test_header_decoder(LZMA_FORMAT_ERROR));
        buffer[5] ^= 1;

        // Test 2a (valid CRC32)
        uint32_t crc = lzma_crc32(buffer + 6, 2, 0);
        unaligned_write32le(buffer + 8, crc);
        succeed(test_header_decoder(LZMA_OK));

        // Test 2b (invalid Stream Flags with valid CRC32)
        buffer[6] ^= 0x20;
        crc = lzma_crc32(buffer + 6, 2, 0);
        unaligned_write32le(buffer + 8, crc);
        succeed(test_header_decoder(LZMA_OPTIONS_ERROR));

        // Test 3 (invalid CRC32)
        expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);
        buffer[9] ^= 1;
        succeed(test_header_decoder(LZMA_DATA_ERROR));

        // Test 4 (invalid Stream Flags with valid CRC32)
        expect(lzma_stream_footer_encode(&known_flags, buffer) == LZMA_OK);
        buffer[9] ^= 0x40;
        crc = lzma_crc32(buffer + 4, 6, 0);
        unaligned_write32le(buffer, crc);
        succeed(test_footer_decoder(LZMA_OPTIONS_ERROR));

        // Test 5 (invalid Magic Bytes)
        expect(lzma_stream_footer_encode(&known_flags, buffer) == LZMA_OK);
        buffer[11] ^= 1;
        succeed(test_footer_decoder(LZMA_FORMAT_ERROR));
}


int
main(void)
{
        // Valid headers
        known_flags.backward_size = 1024;
        for (lzma_check check = LZMA_CHECK_NONE;
                        check <= LZMA_CHECK_ID_MAX; ++check) {
                test_header();
                test_footer();
        }

        // Invalid headers
        test_encode_invalid();
        test_decode_invalid();

        return 0;
}

/* [<][>][^][v][top][bottom][index][help] */