// SPDX-License-Identifier: GPL-2.0-or-later #include #include #define SW842_GUARD_SIZE 8 #define SW842_MAX_OUTPUT 16 #define SW842_GUARD_BYTE 0x42 #define SW842_OUTPUT_POISON 0x5a /* ZEROS, I8(0), END, CRC32. */ static const u8 sw842_index_exact_fit[] = { 0xe6, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, }; /* D8(eight zero bytes), I8(0), END, CRC32. */ static const u8 sw842_index_output_overflow[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, }; /* ZEROS, SHORT_DATA(01 02 03 04 05), END, CRC32. */ static const u8 sw842_short_data_exact_fit[] = { 0xe7, 0x68, 0x08, 0x10, 0x18, 0x20, 0x2f, 0xa9, 0x67, 0xfc, 0x07, 0xc0, }; /* ZEROS, SHORT_DATA(five zero bytes), END, CRC32. */ static const u8 sw842_short_data_output_overflow[] = { 0xe7, 0x48, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, }; /* ZEROS, REPEAT(one block), END, CRC32. */ static const u8 sw842_repeat_exact_history[] = { 0xe6, 0xc0, 0xf0, 0x00, 0x00, 0x00, 0x00, }; /* * SHORT_DATA(seven zero bytes), REPEAT(one block), END, CRC32. * CRC32 includes SW842_GUARD_BYTE copied from before output into byte 7. */ static const u8 sw842_repeat_without_full_history[] = { 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x1e, 0x09, 0xa3, 0x1d, 0xd6, }; static const u8 sw842_zero_output[SW842_MAX_OUTPUT]; static const u8 sw842_short_data_output[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, }; struct sw842_decompress_test_case { const char *name; const u8 *compressed; unsigned int compressed_len; const u8 *expected_output; unsigned int output_capacity; int expected_ret; }; #define SW842_DECOMPRESS_CASE(_name, _compressed, _compressed_len, _expected, \ _capacity, _ret) \ { \ .name = _name, \ .compressed = _compressed, \ .compressed_len = _compressed_len, \ .expected_output = _expected, \ .output_capacity = _capacity, \ .expected_ret = _ret, \ } static const struct sw842_decompress_test_case sw842_decompress_cases[] = { SW842_DECOMPRESS_CASE("index_exact_fit", sw842_index_exact_fit, ARRAY_SIZE(sw842_index_exact_fit), sw842_zero_output, 16, 0), SW842_DECOMPRESS_CASE("index_output_overflow", sw842_index_output_overflow, ARRAY_SIZE(sw842_index_output_overflow), sw842_zero_output, 8, -ENOSPC), SW842_DECOMPRESS_CASE("short_data_exact_fit", sw842_short_data_exact_fit, ARRAY_SIZE(sw842_short_data_exact_fit), sw842_short_data_output, sizeof(sw842_short_data_output), 0), SW842_DECOMPRESS_CASE("short_data_output_overflow", sw842_short_data_output_overflow, ARRAY_SIZE(sw842_short_data_output_overflow), sw842_zero_output, 8, -ENOSPC), SW842_DECOMPRESS_CASE("repeat_exact_history", sw842_repeat_exact_history, ARRAY_SIZE(sw842_repeat_exact_history), sw842_zero_output, 16, 0), SW842_DECOMPRESS_CASE("repeat_without_full_history", sw842_repeat_without_full_history, ARRAY_SIZE(sw842_repeat_without_full_history), sw842_zero_output, 15, -EINVAL), }; KUNIT_ARRAY_PARAM_DESC(sw842_decompress, sw842_decompress_cases, name); static void sw842_decompress_test(struct kunit *test) { const struct sw842_decompress_test_case *test_case = test->param_value; u8 storage[SW842_GUARD_SIZE + SW842_MAX_OUTPUT + SW842_GUARD_SIZE]; u8 expected_guard[SW842_GUARD_SIZE]; u8 *output = storage + SW842_GUARD_SIZE; unsigned int output_len = test_case->output_capacity; int ret; KUNIT_ASSERT_LE(test, test_case->output_capacity, SW842_MAX_OUTPUT); memset(storage, SW842_GUARD_BYTE, sizeof(storage)); memset(expected_guard, SW842_GUARD_BYTE, sizeof(expected_guard)); memset(output, SW842_OUTPUT_POISON, test_case->output_capacity); ret = sw842_decompress(test_case->compressed, test_case->compressed_len, output, &output_len); KUNIT_EXPECT_EQ(test, ret, test_case->expected_ret); /* Every successful case is an exact-fit boundary test. */ KUNIT_EXPECT_EQ(test, output_len, test_case->expected_ret ? 0U : test_case->output_capacity); if (!test_case->expected_ret) KUNIT_EXPECT_MEMEQ(test, output, test_case->expected_output, test_case->output_capacity); KUNIT_EXPECT_MEMEQ(test, storage, expected_guard, SW842_GUARD_SIZE); KUNIT_EXPECT_MEMEQ(test, output + test_case->output_capacity, expected_guard, SW842_GUARD_SIZE); } static struct kunit_case sw842_decompress_test_cases[] = { KUNIT_CASE_PARAM(sw842_decompress_test, sw842_decompress_gen_params), {} }; static struct kunit_suite sw842_decompress_test_suite = { .name = "842-decompress", .test_cases = sw842_decompress_test_cases, }; kunit_test_suite(sw842_decompress_test_suite); MODULE_DESCRIPTION("Software 842 decompressor KUnit tests"); MODULE_LICENSE("GPL");