// SPDX-License-Identifier: 0BSD /////////////////////////////////////////////////////////////////////////////// // /// \file test_memlimit.c /// \brief Tests memory usage limit in decoders // // Author: Lasse Collin // /////////////////////////////////////////////////////////////////////////////// #include "tests.h" #include "mythread.h" #define MEMLIMIT_TOO_LOW 1234U #define MEMLIMIT_HIGH_ENOUGH (2U << 20) static uint8_t *in; static size_t in_size; #ifdef HAVE_DECODERS static uint8_t out[8192]; #endif static void test_memlimit_stream_decoder(void) { #ifndef HAVE_DECODERS assert_skip("Decoder support disabled"); #else lzma_stream strm = LZMA_STREAM_INIT; assert_lzma_ret(lzma_stream_decoder(&strm, MEMLIMIT_TOO_LOW, 0), LZMA_OK); strm.next_in = in; strm.avail_in = in_size; strm.next_out = out; strm.avail_out = sizeof(out); assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_MEMLIMIT_ERROR); assert_uint_eq(lzma_memlimit_get(&strm), MEMLIMIT_TOO_LOW); assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_TOO_LOW + 1), LZMA_MEMLIMIT_ERROR); assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_HIGH_ENOUGH), LZMA_OK); // This fails before commit 660739f99ab211edec4071de98889fb32ed04e98 // (liblzma <= 5.2.6, liblzma <= 5.3.3alpha). It was fixed in 5.2.7. assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); lzma_end(&strm); #endif } static void test_memlimit_stream_decoder_mt(void) { #ifndef MYTHREAD_ENABLED assert_skip("Threading support disabled"); #elif !defined(HAVE_DECODERS) assert_skip("Decoder support disabled"); #else lzma_stream strm = LZMA_STREAM_INIT; lzma_mt mt = { .flags = 0, .threads = 1, .timeout = 0, .memlimit_threading = 0, .memlimit_stop = MEMLIMIT_TOO_LOW, }; assert_lzma_ret(lzma_stream_decoder_mt(&strm, &mt), LZMA_OK); strm.next_in = in; strm.avail_in = in_size; strm.next_out = out; strm.avail_out = sizeof(out); assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_MEMLIMIT_ERROR); assert_uint_eq(lzma_memlimit_get(&strm), MEMLIMIT_TOO_LOW); assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_TOO_LOW + 1), LZMA_MEMLIMIT_ERROR); assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_HIGH_ENOUGH), LZMA_OK); assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); lzma_end(&strm); #endif } static void test_memlimit_alone_decoder(void) { #ifndef HAVE_DECODERS assert_skip("Decoder support disabled"); #else size_t alone_size; uint8_t *alone_buf = tuktest_file_from_srcdir( "files/good-unknown_size-with_eopm.lzma", &alone_size); lzma_stream strm = LZMA_STREAM_INIT; assert_lzma_ret(lzma_alone_decoder(&strm, MEMLIMIT_TOO_LOW), LZMA_OK); strm.next_in = alone_buf; strm.avail_in = alone_size; strm.next_out = out; strm.avail_out = sizeof(out); assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_MEMLIMIT_ERROR); assert_uint_eq(lzma_memlimit_get(&strm), MEMLIMIT_TOO_LOW); assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_TOO_LOW + 1), LZMA_MEMLIMIT_ERROR); assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_HIGH_ENOUGH), LZMA_OK); assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); lzma_end(&strm); #endif } static void test_memlimit_auto_decoder(void) { #ifndef HAVE_DECODERS assert_skip("Decoder support disabled"); #else lzma_stream strm = LZMA_STREAM_INIT; assert_lzma_ret(lzma_auto_decoder(&strm, MEMLIMIT_TOO_LOW, 0), LZMA_OK); strm.next_in = in; strm.avail_in = in_size; strm.next_out = out; strm.avail_out = sizeof(out); assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_MEMLIMIT_ERROR); assert_uint_eq(lzma_memlimit_get(&strm), MEMLIMIT_TOO_LOW); assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_TOO_LOW + 1), LZMA_MEMLIMIT_ERROR); assert_lzma_ret(lzma_memlimit_set(&strm, MEMLIMIT_HIGH_ENOUGH), LZMA_OK); assert_lzma_ret(lzma_code(&strm, LZMA_FINISH), LZMA_STREAM_END); lzma_end(&strm); #endif } extern int main(int argc, char **argv) { tuktest_start(argc, argv); in = tuktest_file_from_srcdir("files/good-1-check-crc32.xz", &in_size); tuktest_run(test_memlimit_stream_decoder); tuktest_run(test_memlimit_stream_decoder_mt); tuktest_run(test_memlimit_alone_decoder); tuktest_run(test_memlimit_auto_decoder); return tuktest_end(); }