lzmainfo: Avoid integer overflow
[xz/debian.git] / tests / test_bcj_exact_size.c
blobfa82f0d760508bf415d8cdb1b08854d661ee786c
1 // SPDX-License-Identifier: 0BSD
3 ///////////////////////////////////////////////////////////////////////////////
4 //
5 /// \file test_bcj_exact_size.c
6 /// \brief Tests BCJ decoding when the output size is known
7 ///
8 /// These tests fail with XZ Utils 5.0.3 and earlier.
9 //
10 // Author: Lasse Collin
12 ///////////////////////////////////////////////////////////////////////////////
14 #include "tests.h"
17 static void
18 test_exact_size(void)
20 #if !defined(HAVE_ENCODERS) || !defined(HAVE_DECODERS)
21 assert_skip("Encoder or decoder support disabled");
22 #else
23 if (!lzma_filter_encoder_is_supported(LZMA_FILTER_POWERPC)
24 || !lzma_filter_decoder_is_supported(
25 LZMA_FILTER_POWERPC))
26 assert_skip("PowerPC BCJ encoder and/or decoder "
27 "is disabled");
29 // Something to be compressed
30 const uint8_t in[16] = "0123456789ABCDEF";
32 // in[] after compression
33 uint8_t compressed[1024];
34 size_t compressed_size = 0;
36 // Output buffer for decompressing compressed[]
37 uint8_t out[sizeof(in)];
39 // Compress with PowerPC BCJ and LZMA2. PowerPC BCJ is used because
40 // it has fixed 4-byte alignment which makes triggering the potential
41 // bug easy.
42 lzma_options_lzma opt_lzma2;
43 assert_false(lzma_lzma_preset(&opt_lzma2, 0));
45 lzma_filter filters[3] = {
46 { .id = LZMA_FILTER_POWERPC, .options = NULL },
47 { .id = LZMA_FILTER_LZMA2, .options = &opt_lzma2 },
48 { .id = LZMA_VLI_UNKNOWN, .options = NULL },
51 assert_lzma_ret(lzma_stream_buffer_encode(
52 filters, LZMA_CHECK_CRC32, NULL,
53 in, sizeof(in),
54 compressed, &compressed_size, sizeof(compressed)),
55 LZMA_OK);
57 // Decompress so that we won't give more output space than
58 // the Stream will need.
59 lzma_stream strm = LZMA_STREAM_INIT;
60 assert_lzma_ret(lzma_stream_decoder(&strm, 10 << 20, 0), LZMA_OK);
62 strm.next_in = compressed;
63 strm.next_out = out;
65 while (true) {
66 if (strm.total_in < compressed_size)
67 strm.avail_in = 1;
69 const lzma_ret ret = lzma_code(&strm, LZMA_RUN);
70 if (ret == LZMA_STREAM_END) {
71 assert_uint_eq(strm.total_in, compressed_size);
72 assert_uint_eq(strm.total_out, sizeof(in));
73 lzma_end(&strm);
74 return;
77 assert_lzma_ret(ret, LZMA_OK);
79 if (strm.total_out < sizeof(in))
80 strm.avail_out = 1;
82 #endif
86 static void
87 test_empty_block(void)
89 #ifndef HAVE_DECODERS
90 assert_skip("Decoder support disabled");
91 #else
92 if (!lzma_filter_decoder_is_supported(LZMA_FILTER_POWERPC))
93 assert_skip("PowerPC BCJ decoder is disabled");
95 // An empty file with one Block using PowerPC BCJ and LZMA2.
96 size_t in_size;
97 uint8_t *empty_bcj_lzma2 = tuktest_file_from_srcdir(
98 "files/good-1-empty-bcj-lzma2.xz", &in_size);
100 // Decompress without giving any output space.
101 uint64_t memlimit = 1 << 20;
102 uint8_t out[1];
103 size_t in_pos = 0;
104 size_t out_pos = 0;
105 assert_lzma_ret(lzma_stream_buffer_decode(&memlimit, 0, NULL,
106 empty_bcj_lzma2, &in_pos, in_size, out, &out_pos, 0),
107 LZMA_OK);
108 assert_uint_eq(in_pos, in_size);
109 assert_uint_eq(out_pos, 0);
110 #endif
114 extern int
115 main(int argc, char **argv)
117 tuktest_start(argc, argv);
119 tuktest_run(test_exact_size);
120 tuktest_run(test_empty_block);
122 return tuktest_end();