1 // SPDX-License-Identifier: 0BSD
3 ///////////////////////////////////////////////////////////////////////////////
5 /// \file test_filter_str.c
6 /// \brief Tests Filter string functions
10 ///////////////////////////////////////////////////////////////////////////////
16 test_lzma_str_to_filters(void)
18 lzma_filter filters
[LZMA_FILTERS_MAX
+ 1];
21 // Test with NULL string.
22 assert_true(lzma_str_to_filters(NULL
, &error_pos
, filters
, 0,
25 // Test with NULL filter array.
26 assert_true(lzma_str_to_filters("lzma2", &error_pos
, NULL
, 0,
29 // Test with unsupported flags.
30 assert_true(lzma_str_to_filters("lzma2", &error_pos
, filters
,
31 UINT32_MAX
, NULL
) != NULL
);
33 assert_true(lzma_str_to_filters("lzma2", &error_pos
, filters
,
34 LZMA_STR_NO_SPACES
<< 1, NULL
) != NULL
);
36 assert_true(lzma_str_to_filters("lzma2", &error_pos
, filters
,
37 LZMA_STR_NO_SPACES
, NULL
) != NULL
);
39 // Test with empty string.
40 assert_true(lzma_str_to_filters("", &error_pos
,
41 filters
, 0, NULL
) != NULL
);
42 assert_int_eq(error_pos
, 0);
44 // Test with invalid filter name and missing filter name.
45 assert_true(lzma_str_to_filters("lzma2 abcd", &error_pos
,
46 filters
, 0, NULL
) != NULL
);
47 assert_int_eq(error_pos
, 6);
49 assert_true(lzma_str_to_filters("lzma2--abcd", &error_pos
,
50 filters
, 0, NULL
) != NULL
);
51 assert_int_eq(error_pos
, 7);
53 assert_true(lzma_str_to_filters("lzma2--", &error_pos
,
54 filters
, 0, NULL
) != NULL
);
55 assert_int_eq(error_pos
, 7);
57 // Test LZMA_STR_ALL_FILTERS flag (should work with LZMA1 if built).
58 #if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1)
59 // Using LZMA1 as a Filter should fail without LZMA_STR_ALL_FILTERS.
60 assert_true(lzma_str_to_filters("lzma1", &error_pos
, filters
,
62 assert_int_eq(error_pos
, 0);
64 assert_true(lzma_str_to_filters("lzma1", &error_pos
, filters
,
65 LZMA_STR_ALL_FILTERS
, NULL
) == NULL
);
67 // Verify Filters array IDs are correct. The array should contain
70 // 2. LZMA_VLI_UNKNOWN filter array terminator
71 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA1
);
72 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
74 lzma_filters_free(filters
, NULL
);
77 // Test LZMA_STR_NO_VALIDATION flag. This should allow having the
78 // same Filter multiple times in the chain and having a non-last
79 // Filter like lzma2 appear before another Filter.
80 // Without the flag, "lzma2 lzma2" must fail.
81 assert_true(lzma_str_to_filters("lzma2 lzma2", &error_pos
, filters
,
84 assert_true(lzma_str_to_filters("lzma2 lzma2", &error_pos
, filters
,
85 LZMA_STR_NO_VALIDATION
, NULL
) == NULL
);
87 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
88 assert_uint_eq(filters
[1].id
, LZMA_FILTER_LZMA2
);
89 assert_uint_eq(filters
[2].id
, LZMA_VLI_UNKNOWN
);
91 lzma_filters_free(filters
, NULL
);
93 // Should fail with invalid Filter options (lc + lp must be <= 4).
94 assert_true(lzma_str_to_filters("lzma2:lc=3,lp=3", &error_pos
, filters
,
95 LZMA_STR_NO_VALIDATION
, NULL
) != NULL
);
97 // Test invalid option name.
98 assert_true(lzma_str_to_filters("lzma2:foo=1,bar=2", &error_pos
,
99 filters
, 0, NULL
) != NULL
);
100 assert_int_eq(error_pos
, 6);
102 // Test missing option value.
103 assert_true(lzma_str_to_filters("lzma2:lc=", &error_pos
,
104 filters
, 0, NULL
) != NULL
);
105 assert_int_eq(error_pos
, 9);
107 assert_true(lzma_str_to_filters("lzma2:=,pb=1", &error_pos
,
108 filters
, 0, NULL
) != NULL
);
109 assert_int_eq(error_pos
, 6);
111 // Test unsupported preset value.
112 assert_true(lzma_str_to_filters("-10", &error_pos
,
113 filters
, 0, NULL
) != NULL
);
114 assert_int_eq(error_pos
, 2);
116 assert_true(lzma_str_to_filters("-5f", &error_pos
,
117 filters
, 0, NULL
) != NULL
);
118 assert_int_eq(error_pos
, 2);
120 // Test filter chain too long.
121 assert_true(lzma_str_to_filters("lzma2 lzma2 lzma2 lzma2 lzma2",
122 &error_pos
, filters
, LZMA_STR_NO_VALIDATION
,
124 assert_int_eq(error_pos
, 24);
126 #if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1)
127 // Should fail with a Filter not supported in the .xz format (lzma1).
128 assert_true(lzma_str_to_filters("lzma1", &error_pos
, filters
,
129 LZMA_STR_NO_VALIDATION
, NULL
) != NULL
);
132 // Test setting options with the "=" format.
133 assert_true(lzma_str_to_filters("lzma2=dict=4096,lc=2,lp=2,pb=1,"
134 "mode=fast,nice=3,mf=hc3,depth=10", &error_pos
,
135 filters
, 0, NULL
) == NULL
);
136 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
137 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
139 lzma_options_lzma
*opts
= filters
[0].options
;
140 assert_uint_eq(opts
->dict_size
, 4096);
141 assert_uint_eq(opts
->lc
, 2);
142 assert_uint_eq(opts
->lp
, 2);
143 assert_uint_eq(opts
->pb
, 1);
144 assert_uint_eq(opts
->mode
, LZMA_MODE_FAST
);
145 assert_uint_eq(opts
->nice_len
, 3);
146 assert_uint_eq(opts
->mf
, LZMA_MF_HC3
);
147 assert_uint_eq(opts
->depth
, 10);
149 lzma_filters_free(filters
, NULL
);
151 #if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86)
152 // Test BCJ Filter options.
153 assert_true(lzma_str_to_filters("x86:start=16", &error_pos
, filters
,
154 LZMA_STR_NO_VALIDATION
, NULL
) == NULL
);
156 assert_uint_eq(filters
[0].id
, LZMA_FILTER_X86
);
157 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
159 lzma_options_bcj
*bcj_opts
= filters
[0].options
;
160 assert_uint_eq(bcj_opts
->start_offset
, 16);
162 lzma_filters_free(filters
, NULL
);
165 #if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)
166 // Test Delta Filter options.
167 assert_true(lzma_str_to_filters("delta:dist=20", &error_pos
, filters
,
168 LZMA_STR_NO_VALIDATION
, NULL
) == NULL
);
170 assert_uint_eq(filters
[0].id
, LZMA_FILTER_DELTA
);
171 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
173 lzma_options_delta
*delta_opts
= filters
[0].options
;
174 assert_uint_eq(delta_opts
->dist
, 20);
176 lzma_filters_free(filters
, NULL
);
179 // Test skipping leading spaces.
180 assert_true(lzma_str_to_filters(" lzma2", &error_pos
, filters
,
183 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
184 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
186 lzma_filters_free(filters
, NULL
);
188 // Test skipping trailing spaces.
189 assert_true(lzma_str_to_filters("lzma2 ", &error_pos
, filters
,
192 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
193 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
195 lzma_filters_free(filters
, NULL
);
197 // Test with "--" instead of space separating.
198 assert_true(lzma_str_to_filters("lzma2--lzma2", &error_pos
, filters
,
199 LZMA_STR_NO_VALIDATION
, NULL
) == NULL
);
201 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
202 assert_uint_eq(filters
[1].id
, LZMA_FILTER_LZMA2
);
203 assert_uint_eq(filters
[2].id
, LZMA_VLI_UNKNOWN
);
205 lzma_filters_free(filters
, NULL
);
207 // Test preset with and without leading "-", and with "e".
208 assert_true(lzma_str_to_filters("-3", &error_pos
, filters
,
211 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
212 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
214 lzma_filters_free(filters
, NULL
);
216 assert_true(lzma_str_to_filters("4", &error_pos
, filters
,
219 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
220 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
222 lzma_filters_free(filters
, NULL
);
224 assert_true(lzma_str_to_filters("9e", &error_pos
, filters
,
227 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
228 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
230 lzma_filters_free(filters
, NULL
);
232 // Test using a preset as an lzma2 option.
233 assert_true(lzma_str_to_filters("lzma2:preset=9e", &error_pos
, filters
,
236 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
237 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
239 lzma_filters_free(filters
, NULL
);
241 // Test setting dictionary size with invalid modifier suffix.
242 assert_true(lzma_str_to_filters("lzma2:dict=4096ZiB", &error_pos
, filters
,
245 assert_true(lzma_str_to_filters("lzma2:dict=4096KiBs", &error_pos
, filters
,
248 // Test option that cannot have multiplier modifier.
249 assert_true(lzma_str_to_filters("lzma2:pb=1k", &error_pos
, filters
,
252 // Test option value too large.
253 assert_true(lzma_str_to_filters("lzma2:dict=4096GiB", &error_pos
, filters
,
256 // Test valid uses of multiplier modifiers (k,m,g).
257 assert_true(lzma_str_to_filters("lzma2:dict=4096KiB", &error_pos
, filters
,
260 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
261 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
263 opts
= filters
[0].options
;
264 assert_uint_eq(opts
->dict_size
, 4096 << 10);
266 lzma_filters_free(filters
, NULL
);
268 assert_true(lzma_str_to_filters("lzma2:dict=40Mi", &error_pos
, filters
,
271 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
272 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
274 opts
= filters
[0].options
;
275 assert_uint_eq(opts
->dict_size
, 40 << 20);
277 lzma_filters_free(filters
, NULL
);
279 assert_true(lzma_str_to_filters("lzma2:dict=1g", &error_pos
, filters
,
282 assert_uint_eq(filters
[0].id
, LZMA_FILTER_LZMA2
);
283 assert_uint_eq(filters
[1].id
, LZMA_VLI_UNKNOWN
);
285 opts
= filters
[0].options
;
286 assert_uint_eq(opts
->dict_size
, 1 << 30);
288 lzma_filters_free(filters
, NULL
);
293 test_lzma_str_from_filters(void)
295 lzma_filter filters
[LZMA_FILTERS_MAX
];
296 filters
[0].id
= LZMA_VLI_UNKNOWN
;
298 char *output_str
= NULL
;
300 // Test basic NULL inputs.
301 assert_lzma_ret(lzma_str_from_filters(NULL
, filters
, 0, NULL
),
304 assert_lzma_ret(lzma_str_from_filters(&output_str
, NULL
, 0, NULL
),
307 // Test with empty filters array.
308 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
, 0, NULL
),
311 // Create a simple filter array only containing an LZMA2 Filter.
312 assert_true(lzma_str_to_filters("lzma2", NULL
, filters
, 0, NULL
)
315 // Test with bad flags.
316 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
,
317 LZMA_STR_ALL_FILTERS
, NULL
), LZMA_OPTIONS_ERROR
);
319 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
,
320 LZMA_STR_NO_VALIDATION
, NULL
), LZMA_OPTIONS_ERROR
);
322 // Test with no flags.
323 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
, 0, NULL
),
326 assert_str_eq(output_str
, "lzma2");
329 // Test LZMA_STR_ENCODER flag.
330 // Only the the return value is checked since the actual string
331 // may change in the future (even though it is unlikely).
332 // The order of options or the inclusion of new options could
333 // cause a change in output, so we will avoid hardcoding an
335 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
,
336 LZMA_STR_ENCODER
, NULL
), LZMA_OK
);
339 // Test LZMA_STR_DECODER flag.
340 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
,
341 LZMA_STR_DECODER
, NULL
), LZMA_OK
);
344 // Test LZMA_STR_GETOPT_LONG flag.
345 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
,
346 LZMA_STR_GETOPT_LONG
, NULL
), LZMA_OK
);
349 // Test LZMA_STR_NO_SPACES flag.
350 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
,
351 LZMA_STR_NO_SPACES
, NULL
), LZMA_OK
);
353 // Check to be sure there are no spaces.
354 assert_true(strchr(output_str
, ' ') == NULL
);
358 lzma_filters_free(filters
, NULL
);
360 #if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86)
361 assert_true(lzma_str_to_filters("x86 lzma2", NULL
, filters
, 0, NULL
)
364 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
, 0, NULL
),
367 assert_str_eq(output_str
, "x86 lzma2");
371 // Test setting BCJ option to NULL.
372 assert_false(filters
[0].options
== NULL
);
373 free(filters
[0].options
);
375 filters
[0].options
= NULL
;
377 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
, 0, NULL
),
380 assert_str_eq(output_str
, "x86 lzma2");
382 lzma_filters_free(filters
, NULL
);
386 lzma_options_lzma opts
;
387 assert_false(lzma_lzma_preset(&opts
, LZMA_PRESET_DEFAULT
));
388 // Test with too many Filters (array terminated after 4+ filters).
389 lzma_filter oversized_filters
[LZMA_FILTERS_MAX
+ 2];
391 for (uint32_t i
= 0; i
< ARRAY_SIZE(oversized_filters
) - 1; i
++) {
392 oversized_filters
[i
].id
= LZMA_FILTER_LZMA2
;
393 oversized_filters
[i
].options
= &opts
;
396 oversized_filters
[LZMA_FILTERS_MAX
+ 1].id
= LZMA_VLI_UNKNOWN
;
397 oversized_filters
[LZMA_FILTERS_MAX
+ 1].options
= NULL
;
399 assert_lzma_ret(lzma_str_from_filters(&output_str
, oversized_filters
,
400 0, NULL
), LZMA_OPTIONS_ERROR
);
402 // Test with NULL filter options (when they cannot be NULL).
403 filters
[0].id
= LZMA_FILTER_LZMA2
;
404 filters
[0].options
= NULL
;
405 filters
[1].id
= LZMA_VLI_UNKNOWN
;
407 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
,
408 LZMA_STR_ENCODER
, NULL
), LZMA_OPTIONS_ERROR
);
410 // Test with bad Filter ID.
411 filters
[0].id
= LZMA_VLI_UNKNOWN
- 1;
412 assert_lzma_ret(lzma_str_from_filters(&output_str
, filters
,
413 LZMA_STR_ENCODER
, NULL
), LZMA_OPTIONS_ERROR
);
417 static const char supported_encoders
[][9] = {
419 #ifdef HAVE_ENCODER_X86
422 #ifdef HAVE_ENCODER_POWERPC
425 #ifdef HAVE_ENCODER_IA64
428 #ifdef HAVE_ENCODER_ARM
431 #ifdef HAVE_ENCODER_ARMTHUMB
434 #ifdef HAVE_ENCODER_SPARC
437 #ifdef HAVE_ENCODER_ARM64
440 #ifdef HAVE_ENCODER_DELTA
445 static const char supported_decoders
[][9] = {
447 #ifdef HAVE_DECODER_X86
450 #ifdef HAVE_DECODER_POWERPC
453 #ifdef HAVE_DECODER_IA64
456 #ifdef HAVE_DECODER_ARM
459 #ifdef HAVE_DECODER_ARMTHUMB
462 #ifdef HAVE_DECODER_SPARC
465 #ifdef HAVE_DECODER_ARM64
468 #ifdef HAVE_DECODER_RISCV
471 #ifdef HAVE_DECODER_DELTA
476 static const char supported_filters
[][9] = {
478 #if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86)
481 #if defined(HAVE_ENCODER_POWERPC) || defined(HAVE_DECODER_POWERPC)
484 #if defined(HAVE_ENCODER_IA64) || defined(HAVE_DECODER_IA64)
487 #if defined(HAVE_ENCODER_ARM) || defined(HAVE_DECODER_ARM)
490 #if defined(HAVE_ENCODER_ARMTHUMB) || defined(HAVE_DECODER_ARMTHUMB)
493 #if defined(HAVE_ENCODER_SPARC) || defined(HAVE_DECODER_SPARC)
496 #if defined(HAVE_ENCODER_ARM64) || defined(HAVE_DECODER_ARM64)
499 #if defined(HAVE_ENCODER_RISCV) || defined(HAVE_DECODER_RISCV)
502 #if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)
509 test_lzma_str_list_filters(void)
511 // Test with basic NULL inputs.
512 assert_lzma_ret(lzma_str_list_filters(NULL
, LZMA_VLI_UNKNOWN
, 0,
513 NULL
), LZMA_PROG_ERROR
);
517 // Test with bad flags.
518 assert_lzma_ret(lzma_str_list_filters(&str
, LZMA_VLI_UNKNOWN
,
519 LZMA_STR_NO_VALIDATION
, NULL
), LZMA_OPTIONS_ERROR
);
521 assert_lzma_ret(lzma_str_list_filters(&str
, LZMA_VLI_UNKNOWN
,
522 LZMA_STR_NO_SPACES
, NULL
), LZMA_OPTIONS_ERROR
);
524 // Test with bad Filter ID.
525 assert_lzma_ret(lzma_str_list_filters(&str
, LZMA_VLI_UNKNOWN
- 1,
526 0, NULL
), LZMA_OPTIONS_ERROR
);
528 // Test LZMA_STR_ENCODER flag.
529 assert_lzma_ret(lzma_str_list_filters(&str
, LZMA_VLI_UNKNOWN
,
530 LZMA_STR_ENCODER
, NULL
), LZMA_OK
);
532 for (uint32_t i
= 0; i
< ARRAY_SIZE(supported_encoders
); i
++)
533 assert_str_contains(str
, supported_encoders
[i
]);
537 // Test LZMA_STR_DECODER flag.
538 assert_lzma_ret(lzma_str_list_filters(&str
, LZMA_VLI_UNKNOWN
,
539 LZMA_STR_DECODER
, NULL
), LZMA_OK
);
541 for (uint32_t i
= 0; i
< ARRAY_SIZE(supported_decoders
); i
++)
542 assert_str_contains(str
, supported_decoders
[i
]);
546 // Test LZMA_STR_GETOPT_LONG flag.
547 assert_lzma_ret(lzma_str_list_filters(&str
, LZMA_VLI_UNKNOWN
,
548 LZMA_STR_GETOPT_LONG
, NULL
), LZMA_OK
);
552 // Test LZMA_STR_ALL_FILTERS flag.
553 assert_lzma_ret(lzma_str_list_filters(&str
, LZMA_VLI_UNKNOWN
,
554 LZMA_STR_ALL_FILTERS
, NULL
), LZMA_OK
);
555 #if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1)
556 // With the flag, the string should contain the LZMA1 Filter.
557 assert_str_contains(str
, "lzma1");
561 // If a non .xz filter is specified, it should still list the Filter.
562 assert_lzma_ret(lzma_str_list_filters(&str
, LZMA_FILTER_LZMA1
,
564 assert_str_eq(str
, "lzma1");
568 // Test with no flags.
569 assert_lzma_ret(lzma_str_list_filters(&str
, LZMA_VLI_UNKNOWN
,
572 for (uint32_t i
= 0; i
< ARRAY_SIZE(supported_filters
); i
++)
573 assert_str_contains(str
, supported_filters
[i
]);
575 assert_str_doesnt_contain(str
, "lzma1");
579 // Test providing a Filter ID.
580 assert_lzma_ret(lzma_str_list_filters(&str
, LZMA_FILTER_LZMA2
,
581 LZMA_STR_ALL_FILTERS
, NULL
), LZMA_OK
);
582 assert_str_eq(str
, "lzma2");
589 main(int argc
, char **argv
)
591 tuktest_start(argc
, argv
);
593 tuktest_run(test_lzma_str_to_filters
);
594 tuktest_run(test_lzma_str_from_filters
);
595 tuktest_run(test_lzma_str_list_filters
);
597 return tuktest_end();