xref: /freebsd/contrib/xz/src/liblzma/common/string_conversion.c (revision aa1a8ff2d6dbc51ef058f46f3db5a8bb77967145)
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       string_conversion.c
4 /// \brief      Conversion of strings to filter chain and vice versa
5 //
6 //  Author:     Lasse Collin
7 //
8 //  This file has been put into the public domain.
9 //  You can do whatever you want with this file.
10 //
11 ///////////////////////////////////////////////////////////////////////////////
12 
13 #include "filter_common.h"
14 
15 
16 /////////////////////
17 // String building //
18 /////////////////////
19 
20 /// How much memory to allocate for strings. For now, no realloc is used
21 /// so this needs to be big enough even though there of course is
22 /// an overflow check still.
23 ///
24 /// FIXME? Using a fixed size is wasteful if the application doesn't free
25 /// the string fairly quickly but this can be improved later if needed.
26 #define STR_ALLOC_SIZE 800
27 
28 
29 typedef struct {
30 	char *buf;
31 	size_t pos;
32 } lzma_str;
33 
34 
35 static lzma_ret
36 str_init(lzma_str *str, const lzma_allocator *allocator)
37 {
38 	str->buf = lzma_alloc(STR_ALLOC_SIZE, allocator);
39 	if (str->buf == NULL)
40 		return LZMA_MEM_ERROR;
41 
42 	str->pos = 0;
43 	return LZMA_OK;
44 }
45 
46 
47 static void
48 str_free(lzma_str *str, const lzma_allocator *allocator)
49 {
50 	lzma_free(str->buf, allocator);
51 	return;
52 }
53 
54 
55 static bool
56 str_is_full(const lzma_str *str)
57 {
58 	return str->pos == STR_ALLOC_SIZE - 1;
59 }
60 
61 
62 static lzma_ret
63 str_finish(char **dest, lzma_str *str, const lzma_allocator *allocator)
64 {
65 	if (str_is_full(str)) {
66 		// The preallocated buffer was too small.
67 		// This shouldn't happen as STR_ALLOC_SIZE should
68 		// be adjusted if new filters are added.
69 		lzma_free(str->buf, allocator);
70 		*dest = NULL;
71 		assert(0);
72 		return LZMA_PROG_ERROR;
73 	}
74 
75 	str->buf[str->pos] = '\0';
76 	*dest = str->buf;
77 	return LZMA_OK;
78 }
79 
80 
81 static void
82 str_append_str(lzma_str *str, const char *s)
83 {
84 	const size_t len = strlen(s);
85 	const size_t limit = STR_ALLOC_SIZE - 1 - str->pos;
86 	const size_t copy_size = my_min(len, limit);
87 
88 	memcpy(str->buf + str->pos, s, copy_size);
89 	str->pos += copy_size;
90 	return;
91 }
92 
93 
94 static void
95 str_append_u32(lzma_str *str, uint32_t v, bool use_byte_suffix)
96 {
97 	if (v == 0) {
98 		str_append_str(str, "0");
99 	} else {
100 		// NOTE: Don't use plain "B" because xz and the parser in this
101 		// file don't support it and at glance it may look like 8
102 		// (there cannot be a space before the suffix).
103 		static const char suffixes[4][4] = { "", "KiB", "MiB", "GiB" };
104 
105 		size_t suf = 0;
106 		if (use_byte_suffix) {
107 			while ((v & 1023) == 0
108 					&& suf < ARRAY_SIZE(suffixes) - 1) {
109 				v >>= 10;
110 				++suf;
111 			}
112 		}
113 
114 		// UINT32_MAX in base 10 would need 10 + 1 bytes. Remember
115 		// that initializing to "" initializes all elements to
116 		// zero so '\0'-termination gets handled by this.
117 		char buf[16] = "";
118 		size_t pos = sizeof(buf) - 1;
119 
120 		do {
121 			buf[--pos] = '0' + (v % 10);
122 			v /= 10;
123 		} while (v != 0);
124 
125 		str_append_str(str, buf + pos);
126 		str_append_str(str, suffixes[suf]);
127 	}
128 
129 	return;
130 }
131 
132 
133 //////////////////////////////////////////////
134 // Parsing and stringification declarations //
135 //////////////////////////////////////////////
136 
137 /// Maximum length for filter and option names.
138 /// 11 chars + terminating '\0' + sizeof(uint32_t) = 16 bytes
139 #define NAME_LEN_MAX 11
140 
141 
142 /// For option_map.flags: Use .u.map to do convert the input value
143 /// to an integer. Without this flag, .u.range.{min,max} are used
144 /// as the allowed range for the integer.
145 #define OPTMAP_USE_NAME_VALUE_MAP 0x01
146 
147 /// For option_map.flags: Allow KiB/MiB/GiB in input string and use them in
148 /// the stringified output if the value is an exact multiple of these.
149 /// This is used e.g. for LZMA1/2 dictionary size.
150 #define OPTMAP_USE_BYTE_SUFFIX 0x02
151 
152 /// For option_map.flags: If the integer value is zero then this option
153 /// won't be included in the stringified output. It's used e.g. for
154 /// BCJ filter start offset which usually is zero.
155 #define OPTMAP_NO_STRFY_ZERO 0x04
156 
157 /// Possible values for option_map.type. Since OPTMAP_TYPE_UINT32 is 0,
158 /// it doesn't need to be specified in the initializers as it is
159 /// the implicit value.
160 enum {
161 	OPTMAP_TYPE_UINT32,
162 	OPTMAP_TYPE_LZMA_MODE,
163 	OPTMAP_TYPE_LZMA_MATCH_FINDER,
164 	OPTMAP_TYPE_LZMA_PRESET,
165 };
166 
167 
168 /// This is for mapping string values in options to integers.
169 /// The last element of an array must have "" as the name.
170 /// It's used e.g. for match finder names in LZMA1/2.
171 typedef struct {
172 	const char name[NAME_LEN_MAX + 1];
173 	const uint32_t value;
174 } name_value_map;
175 
176 
177 /// Each filter that has options needs an array of option_map structures.
178 /// The array doesn't need to be terminated as the functions take the
179 /// length of the array as an argument.
180 ///
181 /// When converting a string to filter options structure, option values
182 /// will be handled in a few different ways:
183 ///
184 /// (1) If .type equals OPTMAP_TYPE_LZMA_PRESET then LZMA1/2 preset string
185 ///     is handled specially.
186 ///
187 /// (2) If .flags has OPTMAP_USE_NAME_VALUE_MAP set then the string is
188 ///     converted to an integer using the name_value_map pointed by .u.map.
189 ///     The last element in .u.map must have .name = "" as the terminator.
190 ///
191 /// (3) Otherwise the string is treated as a non-negative unsigned decimal
192 ///     integer which must be in the range set in .u.range. If .flags has
193 ///     OPTMAP_USE_BYTE_SUFFIX then KiB, MiB, and GiB suffixes are allowed.
194 ///
195 /// The integer value from (2) or (3) is then stored to filter_options
196 /// at the offset specified in .offset using the type specified in .type
197 /// (default is uint32_t).
198 ///
199 /// Stringifying a filter is done by processing a given number of options
200 /// in order from the beginning of an option_map array. The integer is
201 /// read from filter_options at .offset using the type from .type.
202 ///
203 /// If the integer is zero and .flags has OPTMAP_NO_STRFY_ZERO then the
204 /// option is skipped.
205 ///
206 /// If .flags has OPTMAP_USE_NAME_VALUE_MAP set then .u.map will be used
207 /// to convert the option to a string. If the map doesn't contain a string
208 /// for the integer value then "UNKNOWN" is used.
209 ///
210 /// If .flags doesn't have OPTMAP_USE_NAME_VALUE_MAP set then the integer is
211 /// converted to a decimal value. If OPTMAP_USE_BYTE_SUFFIX is used then KiB,
212 /// MiB, or GiB suffix is used if the value is an exact multiple of these.
213 /// Plain "B" suffix is never used.
214 typedef struct {
215 	char name[NAME_LEN_MAX + 1];
216 	uint8_t type;
217 	uint8_t flags;
218 	uint16_t offset;
219 
220 	union {
221 		struct {
222 			uint32_t min;
223 			uint32_t max;
224 		} range;
225 
226 		const name_value_map *map;
227 	} u;
228 } option_map;
229 
230 
231 static const char *parse_options(const char **const str, const char *str_end,
232 		void *filter_options,
233 		const option_map *const optmap, const size_t optmap_size);
234 
235 
236 /////////
237 // BCJ //
238 /////////
239 
240 #if defined(HAVE_ENCODER_X86) \
241 		|| defined(HAVE_DECODER_X86) \
242 		|| defined(HAVE_ENCODER_ARM) \
243 		|| defined(HAVE_DECODER_ARM) \
244 		|| defined(HAVE_ENCODER_ARMTHUMB) \
245 		|| defined(HAVE_DECODER_ARMTHUMB) \
246 		|| defined(HAVE_ENCODER_ARM64) \
247 		|| defined(HAVE_DECODER_ARM64) \
248 		|| defined(HAVE_ENCODER_POWERPC) \
249 		|| defined(HAVE_DECODER_POWERPC) \
250 		|| defined(HAVE_ENCODER_IA64) \
251 		|| defined(HAVE_DECODER_IA64) \
252 		|| defined(HAVE_ENCODER_SPARC) \
253 		|| defined(HAVE_DECODER_SPARC)
254 static const option_map bcj_optmap[] = {
255 	{
256 		.name = "start",
257 		.flags = OPTMAP_NO_STRFY_ZERO | OPTMAP_USE_BYTE_SUFFIX,
258 		.offset = offsetof(lzma_options_bcj, start_offset),
259 		.u.range.min = 0,
260 		.u.range.max = UINT32_MAX,
261 	}
262 };
263 
264 
265 static const char *
266 parse_bcj(const char **const str, const char *str_end, void *filter_options)
267 {
268 	// filter_options was zeroed on allocation and that is enough
269 	// for the default value.
270 	return parse_options(str, str_end, filter_options,
271 			bcj_optmap, ARRAY_SIZE(bcj_optmap));
272 }
273 #endif
274 
275 
276 ///////////
277 // Delta //
278 ///////////
279 
280 #if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)
281 static const option_map delta_optmap[] = {
282 	{
283 		.name = "dist",
284 		.offset = offsetof(lzma_options_delta, dist),
285 		.u.range.min = LZMA_DELTA_DIST_MIN,
286 		.u.range.max = LZMA_DELTA_DIST_MAX,
287 	}
288 };
289 
290 
291 static const char *
292 parse_delta(const char **const str, const char *str_end, void *filter_options)
293 {
294 	lzma_options_delta *opts = filter_options;
295 	opts->type = LZMA_DELTA_TYPE_BYTE;
296 	opts->dist = LZMA_DELTA_DIST_MIN;
297 
298 	return parse_options(str, str_end, filter_options,
299 			delta_optmap, ARRAY_SIZE(delta_optmap));
300 }
301 #endif
302 
303 
304 ///////////////////
305 // LZMA1 & LZMA2 //
306 ///////////////////
307 
308 /// Help string for presets
309 #define LZMA12_PRESET_STR "0-9[e]"
310 
311 
312 static const char *
313 parse_lzma12_preset(const char **const str, const char *str_end,
314 		uint32_t *preset)
315 {
316 	assert(*str < str_end);
317 	*preset = (uint32_t)(**str - '0');
318 
319 	// NOTE: Remember to update LZMA12_PRESET_STR if this is modified!
320 	while (++*str < str_end) {
321 		switch (**str) {
322 		case 'e':
323 			*preset |= LZMA_PRESET_EXTREME;
324 			break;
325 
326 		default:
327 			return "Unsupported preset flag";
328 		}
329 	}
330 
331 	return NULL;
332 }
333 
334 
335 static const char *
336 set_lzma12_preset(const char **const str, const char *str_end,
337 		void *filter_options)
338 {
339 	uint32_t preset;
340 	const char *errmsg = parse_lzma12_preset(str, str_end, &preset);
341 	if (errmsg != NULL)
342 		return errmsg;
343 
344 	lzma_options_lzma *opts = filter_options;
345 	if (lzma_lzma_preset(opts, preset))
346 		return "Unsupported preset";
347 
348 	return NULL;
349 }
350 
351 
352 static const name_value_map lzma12_mode_map[] = {
353 	{ "fast",   LZMA_MODE_FAST },
354 	{ "normal", LZMA_MODE_NORMAL },
355 	{ "",       0 }
356 };
357 
358 
359 static const name_value_map lzma12_mf_map[] = {
360 	{ "hc3", LZMA_MF_HC3 },
361 	{ "hc4", LZMA_MF_HC4 },
362 	{ "bt2", LZMA_MF_BT2 },
363 	{ "bt3", LZMA_MF_BT3 },
364 	{ "bt4", LZMA_MF_BT4 },
365 	{ "",    0 }
366 };
367 
368 
369 static const option_map lzma12_optmap[] = {
370 	{
371 		.name = "preset",
372 		.type = OPTMAP_TYPE_LZMA_PRESET,
373 	}, {
374 		.name = "dict",
375 		.flags = OPTMAP_USE_BYTE_SUFFIX,
376 		.offset = offsetof(lzma_options_lzma, dict_size),
377 		.u.range.min = LZMA_DICT_SIZE_MIN,
378 		// FIXME? The max is really max for encoding but decoding
379 		// would allow 4 GiB - 1 B.
380 		.u.range.max = (UINT32_C(1) << 30) + (UINT32_C(1) << 29),
381 	}, {
382 		.name = "lc",
383 		.offset = offsetof(lzma_options_lzma, lc),
384 		.u.range.min = LZMA_LCLP_MIN,
385 		.u.range.max = LZMA_LCLP_MAX,
386 	}, {
387 		.name = "lp",
388 		.offset = offsetof(lzma_options_lzma, lp),
389 		.u.range.min = LZMA_LCLP_MIN,
390 		.u.range.max = LZMA_LCLP_MAX,
391 	}, {
392 		.name = "pb",
393 		.offset = offsetof(lzma_options_lzma, pb),
394 		.u.range.min = LZMA_PB_MIN,
395 		.u.range.max = LZMA_PB_MAX,
396 	}, {
397 		.name = "mode",
398 		.type = OPTMAP_TYPE_LZMA_MODE,
399 		.flags = OPTMAP_USE_NAME_VALUE_MAP,
400 		.offset = offsetof(lzma_options_lzma, mode),
401 		.u.map = lzma12_mode_map,
402 	}, {
403 		.name = "nice",
404 		.offset = offsetof(lzma_options_lzma, nice_len),
405 		.u.range.min = 2,
406 		.u.range.max = 273,
407 	}, {
408 		.name = "mf",
409 		.type = OPTMAP_TYPE_LZMA_MATCH_FINDER,
410 		.flags = OPTMAP_USE_NAME_VALUE_MAP,
411 		.offset = offsetof(lzma_options_lzma, mf),
412 		.u.map = lzma12_mf_map,
413 	}, {
414 		.name = "depth",
415 		.offset = offsetof(lzma_options_lzma, depth),
416 		.u.range.min = 0,
417 		.u.range.max = UINT32_MAX,
418 	}
419 };
420 
421 
422 static const char *
423 parse_lzma12(const char **const str, const char *str_end, void *filter_options)
424 {
425 	lzma_options_lzma *opts = filter_options;
426 
427 	// It cannot fail.
428 	const bool preset_ret = lzma_lzma_preset(opts, LZMA_PRESET_DEFAULT);
429 	assert(!preset_ret);
430 	(void)preset_ret;
431 
432 	const char *errmsg = parse_options(str, str_end, filter_options,
433 			lzma12_optmap, ARRAY_SIZE(lzma12_optmap));
434 	if (errmsg != NULL)
435 		return errmsg;
436 
437 	if (opts->lc + opts->lp > LZMA_LCLP_MAX)
438 		return "The sum of lc and lp must not exceed 4";
439 
440 	return NULL;
441 }
442 
443 
444 /////////////////////////////////////////
445 // Generic parsing and stringification //
446 /////////////////////////////////////////
447 
448 static const struct {
449 	/// Name of the filter
450 	char name[NAME_LEN_MAX + 1];
451 
452 	/// For lzma_str_to_filters:
453 	/// Size of the filter-specific options structure.
454 	uint32_t opts_size;
455 
456 	/// Filter ID
457 	lzma_vli id;
458 
459 	/// For lzma_str_to_filters:
460 	/// Function to parse the filter-specific options. The filter_options
461 	/// will already have been allocated using lzma_alloc_zero().
462 	const char *(*parse)(const char **str, const char *str_end,
463 			void *filter_options);
464 
465 	/// For lzma_str_from_filters:
466 	/// If the flag LZMA_STR_ENCODER is used then the first
467 	/// strfy_encoder elements of optmap are stringified.
468 	/// With LZMA_STR_DECODER strfy_decoder is used.
469 	/// Currently encoders use all options that decoders do but if
470 	/// that changes then this needs to be changed too, for example,
471 	/// add a new OPTMAP flag to skip printing some decoder-only options.
472 	const option_map *optmap;
473 	uint8_t strfy_encoder;
474 	uint8_t strfy_decoder;
475 
476 	/// For lzma_str_from_filters:
477 	/// If true, lzma_filter.options is allowed to be NULL. In that case,
478 	/// only the filter name is printed without any options.
479 	bool allow_null;
480 
481 } filter_name_map[] = {
482 #if defined (HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1)
483 	{ "lzma1",        sizeof(lzma_options_lzma),  LZMA_FILTER_LZMA1,
484 	  &parse_lzma12,  lzma12_optmap, 9, 5, false },
485 #endif
486 
487 #if defined(HAVE_ENCODER_LZMA2) || defined(HAVE_DECODER_LZMA2)
488 	{ "lzma2",        sizeof(lzma_options_lzma),  LZMA_FILTER_LZMA2,
489 	  &parse_lzma12,  lzma12_optmap, 9, 2, false },
490 #endif
491 
492 #if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86)
493 	{ "x86",          sizeof(lzma_options_bcj),   LZMA_FILTER_X86,
494 	  &parse_bcj,     bcj_optmap, 1, 1, true },
495 #endif
496 
497 #if defined(HAVE_ENCODER_ARM) || defined(HAVE_DECODER_ARM)
498 	{ "arm",          sizeof(lzma_options_bcj),   LZMA_FILTER_ARM,
499 	  &parse_bcj,     bcj_optmap, 1, 1, true },
500 #endif
501 
502 #if defined(HAVE_ENCODER_ARMTHUMB) || defined(HAVE_DECODER_ARMTHUMB)
503 	{ "armthumb",     sizeof(lzma_options_bcj),   LZMA_FILTER_ARMTHUMB,
504 	  &parse_bcj,     bcj_optmap, 1, 1, true },
505 #endif
506 
507 #if defined(HAVE_ENCODER_ARM64) || defined(HAVE_DECODER_ARM64)
508 	{ "arm64",        sizeof(lzma_options_bcj),   LZMA_FILTER_ARM64,
509 	  &parse_bcj,     bcj_optmap, 1, 1, true },
510 #endif
511 
512 #if defined(HAVE_ENCODER_POWERPC) || defined(HAVE_DECODER_POWERPC)
513 	{ "powerpc",      sizeof(lzma_options_bcj),   LZMA_FILTER_POWERPC,
514 	  &parse_bcj,     bcj_optmap, 1, 1, true },
515 #endif
516 
517 #if defined(HAVE_ENCODER_IA64) || defined(HAVE_DECODER_IA64)
518 	{ "ia64",         sizeof(lzma_options_bcj),   LZMA_FILTER_IA64,
519 	  &parse_bcj,     bcj_optmap, 1, 1, true },
520 #endif
521 
522 #if defined(HAVE_ENCODER_SPARC) || defined(HAVE_DECODER_SPARC)
523 	{ "sparc",        sizeof(lzma_options_bcj),   LZMA_FILTER_SPARC,
524 	  &parse_bcj,     bcj_optmap, 1, 1, true },
525 #endif
526 
527 #if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)
528 	{ "delta",        sizeof(lzma_options_delta), LZMA_FILTER_DELTA,
529 	  &parse_delta,   delta_optmap, 1, 1, false },
530 #endif
531 };
532 
533 
534 /// Decodes options from a string for one filter (name1=value1,name2=value2).
535 /// Caller must have allocated memory for filter_options already and set
536 /// the initial default values. This is called from the filter-specific
537 /// parse_* functions.
538 ///
539 /// The input string starts at *str and the address in str_end is the first
540 /// char that is not part of the string anymore. So no '\0' terminator is
541 /// used. *str is advanced every time something has been decoded successfully.
542 static const char *
543 parse_options(const char **const str, const char *str_end,
544 		void *filter_options,
545 		const option_map *const optmap, const size_t optmap_size)
546 {
547 	while (*str < str_end && **str != '\0') {
548 		// Each option is of the form name=value.
549 		// Commas (',') separate options. Extra commas are ignored.
550 		// Ignoring extra commas makes it simpler if an optional
551 		// option stored in a shell variable which can be empty.
552 		if (**str == ',') {
553 			++*str;
554 			continue;
555 		}
556 
557 		// Find where the next name=value ends.
558 		const size_t str_len = (size_t)(str_end - *str);
559 		const char *name_eq_value_end = memchr(*str, ',', str_len);
560 		if (name_eq_value_end == NULL)
561 			name_eq_value_end = str_end;
562 
563 		const char *equals_sign = memchr(*str, '=',
564 				(size_t)(name_eq_value_end - *str));
565 
566 		// Fail if the '=' wasn't found or the option name is missing
567 		// (the first char is '=').
568 		if (equals_sign == NULL || **str == '=')
569 			return "Options must be 'name=value' pairs separated "
570 					"with commas";
571 
572 		// Reject a too long option name so that the memcmp()
573 		// in the loop below won't read past the end of the
574 		// string in optmap[i].name.
575 		const size_t name_len = (size_t)(equals_sign - *str);
576 		if (name_len > NAME_LEN_MAX)
577 			return "Unknown option name";
578 
579 		// Find the option name from optmap[].
580 		size_t i = 0;
581 		while (true) {
582 			if (i == optmap_size)
583 				return "Unknown option name";
584 
585 			if (memcmp(*str, optmap[i].name, name_len) == 0
586 					&& optmap[i].name[name_len] == '\0')
587 				break;
588 
589 			++i;
590 		}
591 
592 		// The input string is good at least until the start of
593 		// the option value.
594 		*str = equals_sign + 1;
595 
596 		// The code assumes that the option value isn't an empty
597 		// string so check it here.
598 		const size_t value_len = (size_t)(name_eq_value_end - *str);
599 		if (value_len == 0)
600 			return "Option value cannot be empty";
601 
602 		// LZMA1/2 preset has its own parsing function.
603 		if (optmap[i].type == OPTMAP_TYPE_LZMA_PRESET) {
604 			const char *errmsg = set_lzma12_preset(str,
605 					name_eq_value_end, filter_options);
606 			if (errmsg != NULL)
607 				return errmsg;
608 
609 			continue;
610 		}
611 
612 		// It's an integer value.
613 		uint32_t v;
614 		if (optmap[i].flags & OPTMAP_USE_NAME_VALUE_MAP) {
615 			// The integer is picked from a string-to-integer map.
616 			//
617 			// Reject a too long value string so that the memcmp()
618 			// in the loop below won't read past the end of the
619 			// string in optmap[i].u.map[j].name.
620 			if (value_len > NAME_LEN_MAX)
621 				return "Invalid option value";
622 
623 			const name_value_map *map = optmap[i].u.map;
624 			size_t j = 0;
625 			while (true) {
626 				// The array is terminated with an empty name.
627 				if (map[j].name[0] == '\0')
628 					return "Invalid option value";
629 
630 				if (memcmp(*str, map[j].name, value_len) == 0
631 						&& map[j].name[value_len]
632 							== '\0') {
633 					v = map[j].value;
634 					break;
635 				}
636 
637 				++j;
638 			}
639 		} else if (**str < '0' || **str > '9') {
640 			// Note that "max" isn't supported while it is
641 			// supported in xz. It's not useful here.
642 			return "Value is not a non-negative decimal integer";
643 		} else {
644 			// strtoul() has locale-specific behavior so it cannot
645 			// be relied on to get reproducible results since we
646 			// cannot change the locate in a thread-safe library.
647 			// It also needs '\0'-termination.
648 			//
649 			// Use a temporary pointer so that *str will point
650 			// to the beginning of the value string in case
651 			// an error occurs.
652 			const char *p = *str;
653 			v = 0;
654 			do {
655 				if (v > UINT32_MAX / 10)
656 					return "Value out of range";
657 
658 				v *= 10;
659 
660 				const uint32_t add = (uint32_t)(*p - '0');
661 				if (UINT32_MAX - add < v)
662 					return "Value out of range";
663 
664 				v += add;
665 				++p;
666 			} while (p < name_eq_value_end
667 					&& *p >= '0' && *p <= '9');
668 
669 			if (p < name_eq_value_end) {
670 				// Remember this position so that it can be
671 				// used for error messages that are
672 				// specifically about the suffix. (Out of
673 				// range values are about the whole value
674 				// and those error messages point to the
675 				// beginning of the number part,
676 				// not to the suffix.)
677 				const char *multiplier_start = p;
678 
679 				// If multiplier suffix shouldn't be used
680 				// then don't allow them even if the value
681 				// would stay within limits. This is a somewhat
682 				// unnecessary check but it rejects silly
683 				// things like lzma2:pb=0MiB which xz allows.
684 				if ((optmap[i].flags & OPTMAP_USE_BYTE_SUFFIX)
685 						== 0) {
686 					*str = multiplier_start;
687 					return "This option does not support "
688 						"any integer suffixes";
689 				}
690 
691 				uint32_t shift;
692 
693 				switch (*p) {
694 				case 'k':
695 				case 'K':
696 					shift = 10;
697 					break;
698 
699 				case 'm':
700 				case 'M':
701 					shift = 20;
702 					break;
703 
704 				case 'g':
705 				case 'G':
706 					shift = 30;
707 					break;
708 
709 				default:
710 					*str = multiplier_start;
711 					return "Invalid multiplier suffix "
712 							"(KiB, MiB, or GiB)";
713 				}
714 
715 				++p;
716 
717 				// Allow "M", "Mi", "MB", "MiB" and the same
718 				// for the other five characters from the
719 				// switch-statement above. All are handled
720 				// as base-2 (perhaps a mistake, perhaps not).
721 				// Note that 'i' and 'B' are case sensitive.
722 				if (p < name_eq_value_end && *p == 'i')
723 					++p;
724 
725 				if (p < name_eq_value_end && *p == 'B')
726 					++p;
727 
728 				// Now we must have no chars remaining.
729 				if (p < name_eq_value_end) {
730 					*str = multiplier_start;
731 					return "Invalid multiplier suffix "
732 							"(KiB, MiB, or GiB)";
733 				}
734 
735 				if (v > (UINT32_MAX >> shift))
736 					return "Value out of range";
737 
738 				v <<= shift;
739 			}
740 
741 			if (v < optmap[i].u.range.min
742 					|| v > optmap[i].u.range.max)
743 				return "Value out of range";
744 		}
745 
746 		// Set the value in filter_options. Enums are handled
747 		// specially since the underlying type isn't the same
748 		// as uint32_t on all systems.
749 		void *ptr = (char *)filter_options + optmap[i].offset;
750 		switch (optmap[i].type) {
751 		case OPTMAP_TYPE_LZMA_MODE:
752 			*(lzma_mode *)ptr = (lzma_mode)v;
753 			break;
754 
755 		case OPTMAP_TYPE_LZMA_MATCH_FINDER:
756 			*(lzma_match_finder *)ptr = (lzma_match_finder)v;
757 			break;
758 
759 		default:
760 			*(uint32_t *)ptr = v;
761 			break;
762 		}
763 
764 		// This option has been successfully handled.
765 		*str = name_eq_value_end;
766 	}
767 
768 	// No errors.
769 	return NULL;
770 }
771 
772 
773 /// Finds the name of the filter at the beginning of the string and
774 /// calls filter_name_map[i].parse() to decode the filter-specific options.
775 /// The caller must have set str_end so that exactly one filter and its
776 /// options are present without any trailing characters.
777 static const char *
778 parse_filter(const char **const str, const char *str_end, lzma_filter *filter,
779 		const lzma_allocator *allocator, bool only_xz)
780 {
781 	// Search for a colon or equals sign that would separate the filter
782 	// name from filter options. If neither is found, then the input
783 	// string only contains a filter name and there are no options.
784 	//
785 	// First assume that a colon or equals sign won't be found:
786 	const char *name_end = str_end;
787 	const char *opts_start = str_end;
788 
789 	for (const char *p = *str; p < str_end; ++p) {
790 		if (*p == ':' || *p == '=') {
791 			name_end = p;
792 
793 			// Filter options (name1=value1,name2=value2,...)
794 			// begin after the colon or equals sign.
795 			opts_start = p + 1;
796 			break;
797 		}
798 	}
799 
800 	// Reject a too long filter name so that the memcmp()
801 	// in the loop below won't read past the end of the
802 	// string in filter_name_map[i].name.
803 	const size_t name_len = (size_t)(name_end - *str);
804 	if (name_len > NAME_LEN_MAX)
805 		return "Unknown filter name";
806 
807 	for (size_t i = 0; i < ARRAY_SIZE(filter_name_map); ++i) {
808 		if (memcmp(*str, filter_name_map[i].name, name_len) == 0
809 				&& filter_name_map[i].name[name_len] == '\0') {
810 			if (only_xz && filter_name_map[i].id
811 					>= LZMA_FILTER_RESERVED_START)
812 				return "This filter cannot be used in "
813 						"the .xz format";
814 
815 			// Allocate the filter-specific options and
816 			// initialize the memory with zeros.
817 			void *options = lzma_alloc_zero(
818 					filter_name_map[i].opts_size,
819 					allocator);
820 			if (options == NULL)
821 				return "Memory allocation failed";
822 
823 			// Filter name was found so the input string is good
824 			// at least this far.
825 			*str = opts_start;
826 
827 			const char *errmsg = filter_name_map[i].parse(
828 					str, str_end, options);
829 			if (errmsg != NULL) {
830 				lzma_free(options, allocator);
831 				return errmsg;
832 			}
833 
834 			// *filter is modified only when parsing is successful.
835 			filter->id = filter_name_map[i].id;
836 			filter->options = options;
837 			return NULL;
838 		}
839 	}
840 
841 	return "Unknown filter name";
842 }
843 
844 
845 /// Converts the string to a filter chain (array of lzma_filter structures).
846 ///
847 /// *str is advanced every time something has been decoded successfully.
848 /// This way the caller knows where in the string a possible error occurred.
849 static const char *
850 str_to_filters(const char **const str, lzma_filter *filters, uint32_t flags,
851 		const lzma_allocator *allocator)
852 {
853 	const char *errmsg;
854 
855 	// Skip leading spaces.
856 	while (**str == ' ')
857 		++*str;
858 
859 	if (**str == '\0')
860 		return "Empty string is not allowed, "
861 				"try \"6\" if a default value is needed";
862 
863 	// Detect the type of the string.
864 	//
865 	// A string beginning with a digit or a string beginning with
866 	// one dash and a digit are treated as presets. Trailing spaces
867 	// will be ignored too (leading spaces were already ignored above).
868 	//
869 	// For example, "6", "7  ", "-9e", or "  -3  " are treated as presets.
870 	// Strings like "-" or "- " aren't preset.
871 #define MY_IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
872 	if (MY_IS_DIGIT(**str) || (**str == '-' && MY_IS_DIGIT((*str)[1]))) {
873 		if (**str == '-')
874 			++*str;
875 
876 		// Ignore trailing spaces.
877 		const size_t str_len = strlen(*str);
878 		const char *str_end = memchr(*str, ' ', str_len);
879 		if (str_end != NULL) {
880 			// There is at least one trailing space. Check that
881 			// there are no chars other than spaces.
882 			for (size_t i = 1; str_end[i] != '\0'; ++i)
883 				if (str_end[i] != ' ')
884 					return "Unsupported preset";
885 		} else {
886 			// There are no trailing spaces. Use the whole string.
887 			str_end = *str + str_len;
888 		}
889 
890 		uint32_t preset;
891 		errmsg = parse_lzma12_preset(str, str_end, &preset);
892 		if (errmsg != NULL)
893 			return errmsg;
894 
895 		lzma_options_lzma *opts = lzma_alloc(sizeof(*opts), allocator);
896 		if (opts == NULL)
897 			return "Memory allocation failed";
898 
899 		if (lzma_lzma_preset(opts, preset)) {
900 			lzma_free(opts, allocator);
901 			return "Unsupported preset";
902 		}
903 
904 		filters[0].id = LZMA_FILTER_LZMA2;
905 		filters[0].options = opts;
906 		filters[1].id = LZMA_VLI_UNKNOWN;
907 		filters[1].options = NULL;
908 
909 		return NULL;
910 	}
911 
912 	// Not a preset so it must be a filter chain.
913 	//
914 	// If LZMA_STR_ALL_FILTERS isn't used we allow only filters that
915 	// can be used in .xz.
916 	const bool only_xz = (flags & LZMA_STR_ALL_FILTERS) == 0;
917 
918 	// Use a temporary array so that we don't modify the caller-supplied
919 	// one until we know that no errors occurred.
920 	lzma_filter temp_filters[LZMA_FILTERS_MAX + 1];
921 
922 	size_t i = 0;
923 	do {
924 		if (i == LZMA_FILTERS_MAX) {
925 			errmsg = "The maximum number of filters is four";
926 			goto error;
927 		}
928 
929 		// Skip "--" if present.
930 		if ((*str)[0] == '-' && (*str)[1] == '-')
931 			*str += 2;
932 
933 		// Locate the end of "filter:name1=value1,name2=value2",
934 		// stopping at the first "--" or a single space.
935 		const char *filter_end = *str;
936 		while (filter_end[0] != '\0') {
937 			if ((filter_end[0] == '-' && filter_end[1] == '-')
938 					|| filter_end[0] == ' ')
939 				break;
940 
941 			++filter_end;
942 		}
943 
944 		// Inputs that have "--" at the end or "-- " in the middle
945 		// will result in an empty filter name.
946 		if (filter_end == *str) {
947 			errmsg = "Filter name is missing";
948 			goto error;
949 		}
950 
951 		errmsg = parse_filter(str, filter_end, &temp_filters[i],
952 				allocator, only_xz);
953 		if (errmsg != NULL)
954 			goto error;
955 
956 		// Skip trailing spaces.
957 		while (**str == ' ')
958 			++*str;
959 
960 		++i;
961 	} while (**str != '\0');
962 
963 	// Seems to be good, terminate the array so that
964 	// basic validation can be done.
965 	temp_filters[i].id = LZMA_VLI_UNKNOWN;
966 	temp_filters[i].options = NULL;
967 
968 	// Do basic validation if the application didn't prohibit it.
969 	if ((flags & LZMA_STR_NO_VALIDATION) == 0) {
970 		size_t dummy;
971 		const lzma_ret ret = lzma_validate_chain(temp_filters, &dummy);
972 		assert(ret == LZMA_OK || ret == LZMA_OPTIONS_ERROR);
973 		if (ret != LZMA_OK) {
974 			errmsg = "Invalid filter chain "
975 					"('lzma2' missing at the end?)";
976 			goto error;
977 		}
978 	}
979 
980 	// All good. Copy the filters to the application supplied array.
981 	memcpy(filters, temp_filters, (i + 1) * sizeof(lzma_filter));
982 	return NULL;
983 
984 error:
985 	// Free the filter options that were successfully decoded.
986 	while (i-- > 0)
987 		lzma_free(temp_filters[i].options, allocator);
988 
989 	return errmsg;
990 }
991 
992 
993 extern LZMA_API(const char *)
994 lzma_str_to_filters(const char *str, int *error_pos, lzma_filter *filters,
995 		uint32_t flags, const lzma_allocator *allocator)
996 {
997 	if (str == NULL || filters == NULL)
998 		return "Unexpected NULL pointer argument(s) "
999 				"to lzma_str_to_filters()";
1000 
1001 	// Validate the flags.
1002 	const uint32_t supported_flags
1003 			= LZMA_STR_ALL_FILTERS
1004 			| LZMA_STR_NO_VALIDATION;
1005 
1006 	if (flags & ~supported_flags)
1007 		return "Unsupported flags to lzma_str_to_filters()";
1008 
1009 	const char *used = str;
1010 	const char *errmsg = str_to_filters(&used, filters, flags, allocator);
1011 
1012 	if (error_pos != NULL) {
1013 		const size_t n = (size_t)(used - str);
1014 		*error_pos = n > INT_MAX ? INT_MAX : (int)n;
1015 	}
1016 
1017 	return errmsg;
1018 }
1019 
1020 
1021 /// Converts options of one filter to a string.
1022 ///
1023 /// The caller must have already put the filter name in the destination
1024 /// string. Since it is possible that no options will be needed, the caller
1025 /// won't have put a delimiter character (':' or '=') in the string yet.
1026 /// We will add it if at least one option will be added to the string.
1027 static void
1028 strfy_filter(lzma_str *dest, const char *delimiter,
1029 		const option_map *optmap, size_t optmap_count,
1030 		const void *filter_options)
1031 {
1032 	for (size_t i = 0; i < optmap_count; ++i) {
1033 		// No attempt is made to reverse LZMA1/2 preset.
1034 		if (optmap[i].type == OPTMAP_TYPE_LZMA_PRESET)
1035 			continue;
1036 
1037 		// All options have integer values, some just are mapped
1038 		// to a string with a name_value_map. LZMA1/2 preset
1039 		// isn't reversed back to preset=PRESET form.
1040 		uint32_t v;
1041 		const void *ptr
1042 			= (const char *)filter_options + optmap[i].offset;
1043 		switch (optmap[i].type) {
1044 			case OPTMAP_TYPE_LZMA_MODE:
1045 				v = *(const lzma_mode *)ptr;
1046 				break;
1047 
1048 			case OPTMAP_TYPE_LZMA_MATCH_FINDER:
1049 				v = *(const lzma_match_finder *)ptr;
1050 				break;
1051 
1052 			default:
1053 				v = *(const uint32_t *)ptr;
1054 				break;
1055 		}
1056 
1057 		// Skip this if this option should be omitted from
1058 		// the string when the value is zero.
1059 		if (v == 0 && (optmap[i].flags & OPTMAP_NO_STRFY_ZERO))
1060 			continue;
1061 
1062 		// Before the first option we add whatever delimiter
1063 		// the caller gave us. For later options a comma is used.
1064 		str_append_str(dest, delimiter);
1065 		delimiter = ",";
1066 
1067 		// Add the option name and equals sign.
1068 		str_append_str(dest, optmap[i].name);
1069 		str_append_str(dest, "=");
1070 
1071 		if (optmap[i].flags & OPTMAP_USE_NAME_VALUE_MAP) {
1072 			const name_value_map *map = optmap[i].u.map;
1073 			size_t j = 0;
1074 			while (true) {
1075 				if (map[j].name[0] == '\0') {
1076 					str_append_str(dest, "UNKNOWN");
1077 					break;
1078 				}
1079 
1080 				if (map[j].value == v) {
1081 					str_append_str(dest, map[j].name);
1082 					break;
1083 				}
1084 
1085 				++j;
1086 			}
1087 		} else {
1088 			str_append_u32(dest, v,
1089 				optmap[i].flags & OPTMAP_USE_BYTE_SUFFIX);
1090 		}
1091 	}
1092 
1093 	return;
1094 }
1095 
1096 
1097 extern LZMA_API(lzma_ret)
1098 lzma_str_from_filters(char **output_str, const lzma_filter *filters,
1099 		uint32_t flags, const lzma_allocator *allocator)
1100 {
1101 	// On error *output_str is always set to NULL.
1102 	// Do it as the very first step.
1103 	if (output_str == NULL)
1104 		return LZMA_PROG_ERROR;
1105 
1106 	*output_str = NULL;
1107 
1108 	if (filters == NULL)
1109 		return LZMA_PROG_ERROR;
1110 
1111 	// Validate the flags.
1112 	const uint32_t supported_flags
1113 			= LZMA_STR_ENCODER
1114 			| LZMA_STR_DECODER
1115 			| LZMA_STR_GETOPT_LONG
1116 			| LZMA_STR_NO_SPACES;
1117 
1118 	if (flags & ~supported_flags)
1119 		return LZMA_OPTIONS_ERROR;
1120 
1121 	// There must be at least one filter.
1122 	if (filters[0].id == LZMA_VLI_UNKNOWN)
1123 		return LZMA_OPTIONS_ERROR;
1124 
1125 	// Allocate memory for the output string.
1126 	lzma_str dest;
1127 	return_if_error(str_init(&dest, allocator));
1128 
1129 	const bool show_opts = (flags & (LZMA_STR_ENCODER | LZMA_STR_DECODER));
1130 
1131 	const char *opt_delim = (flags & LZMA_STR_GETOPT_LONG) ? "=" : ":";
1132 
1133 	for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
1134 		// If we reach LZMA_FILTERS_MAX, then the filters array
1135 		// is too large since the ID cannot be LZMA_VLI_UNKNOWN here.
1136 		if (i == LZMA_FILTERS_MAX) {
1137 			str_free(&dest, allocator);
1138 			return LZMA_OPTIONS_ERROR;
1139 		}
1140 
1141 		// Don't add a space between filters if the caller
1142 		// doesn't want them.
1143 		if (i > 0 && !(flags & LZMA_STR_NO_SPACES))
1144 			str_append_str(&dest, " ");
1145 
1146 		// Use dashes for xz getopt_long() compatible syntax but also
1147 		// use dashes to separate filters when spaces weren't wanted.
1148 		if ((flags & LZMA_STR_GETOPT_LONG)
1149 				|| (i > 0 && (flags & LZMA_STR_NO_SPACES)))
1150 			str_append_str(&dest, "--");
1151 
1152 		size_t j = 0;
1153 		while (true) {
1154 			if (j == ARRAY_SIZE(filter_name_map)) {
1155 				// Filter ID in filters[i].id isn't supported.
1156 				str_free(&dest, allocator);
1157 				return LZMA_OPTIONS_ERROR;
1158 			}
1159 
1160 			if (filter_name_map[j].id == filters[i].id) {
1161 				// Add the filter name.
1162 				str_append_str(&dest, filter_name_map[j].name);
1163 
1164 				// If only the filter names were wanted then
1165 				// skip to the next filter. In this case
1166 				// .options is ignored and may be NULL even
1167 				// when the filter doesn't allow NULL options.
1168 				if (!show_opts)
1169 					break;
1170 
1171 				if (filters[i].options == NULL) {
1172 					if (!filter_name_map[j].allow_null) {
1173 						// Filter-specific options
1174 						// are missing but with
1175 						// this filter the options
1176 						// structure is mandatory.
1177 						str_free(&dest, allocator);
1178 						return LZMA_OPTIONS_ERROR;
1179 					}
1180 
1181 					// .options is allowed to be NULL.
1182 					// There is no need to add any
1183 					// options to the string.
1184 					break;
1185 				}
1186 
1187 				// Options structure is available. Add
1188 				// the filter options to the string.
1189 				const size_t optmap_count
1190 					= (flags & LZMA_STR_ENCODER)
1191 					? filter_name_map[j].strfy_encoder
1192 					: filter_name_map[j].strfy_decoder;
1193 				strfy_filter(&dest, opt_delim,
1194 						filter_name_map[j].optmap,
1195 						optmap_count,
1196 						filters[i].options);
1197 				break;
1198 			}
1199 
1200 			++j;
1201 		}
1202 	}
1203 
1204 	return str_finish(output_str, &dest, allocator);
1205 }
1206 
1207 
1208 extern LZMA_API(lzma_ret)
1209 lzma_str_list_filters(char **output_str, lzma_vli filter_id, uint32_t flags,
1210 		const lzma_allocator *allocator)
1211 {
1212 	// On error *output_str is always set to NULL.
1213 	// Do it as the very first step.
1214 	if (output_str == NULL)
1215 		return LZMA_PROG_ERROR;
1216 
1217 	*output_str = NULL;
1218 
1219 	// Validate the flags.
1220 	const uint32_t supported_flags
1221 			= LZMA_STR_ALL_FILTERS
1222 			| LZMA_STR_ENCODER
1223 			| LZMA_STR_DECODER
1224 			| LZMA_STR_GETOPT_LONG;
1225 
1226 	if (flags & ~supported_flags)
1227 		return LZMA_OPTIONS_ERROR;
1228 
1229 	// Allocate memory for the output string.
1230 	lzma_str dest;
1231 	return_if_error(str_init(&dest, allocator));
1232 
1233 	// If only listing the filter names then separate them with spaces.
1234 	// Otherwise use newlines.
1235 	const bool show_opts = (flags & (LZMA_STR_ENCODER | LZMA_STR_DECODER));
1236 	const char *filter_delim = show_opts ? "\n" : " ";
1237 
1238 	const char *opt_delim = (flags & LZMA_STR_GETOPT_LONG) ? "=" : ":";
1239 	bool first_filter_printed = false;
1240 
1241 	for (size_t i = 0; i < ARRAY_SIZE(filter_name_map); ++i) {
1242 		// If we are printing only one filter then skip others.
1243 		if (filter_id != LZMA_VLI_UNKNOWN
1244 				&& filter_id != filter_name_map[i].id)
1245 			continue;
1246 
1247 		// If we are printing only .xz filters then skip the others.
1248 		if (filter_name_map[i].id >= LZMA_FILTER_RESERVED_START
1249 				&& (flags & LZMA_STR_ALL_FILTERS) == 0
1250 				&& filter_id == LZMA_VLI_UNKNOWN)
1251 			continue;
1252 
1253 		// Add a new line if this isn't the first filter being
1254 		// written to the string.
1255 		if (first_filter_printed)
1256 			str_append_str(&dest, filter_delim);
1257 
1258 		first_filter_printed = true;
1259 
1260 		if (flags & LZMA_STR_GETOPT_LONG)
1261 			str_append_str(&dest, "--");
1262 
1263 		str_append_str(&dest, filter_name_map[i].name);
1264 
1265 		// If only the filter names were wanted then continue
1266 		// to the next filter.
1267 		if (!show_opts)
1268 			continue;
1269 
1270 		const option_map *optmap = filter_name_map[i].optmap;
1271 		const char *d = opt_delim;
1272 
1273 		const size_t end = (flags & LZMA_STR_ENCODER)
1274 				? filter_name_map[i].strfy_encoder
1275 				: filter_name_map[i].strfy_decoder;
1276 
1277 		for (size_t j = 0; j < end; ++j) {
1278 			// The first option is delimited from the filter
1279 			// name using "=" or ":" and the rest of the options
1280 			// are separated with ",".
1281 			str_append_str(&dest, d);
1282 			d = ",";
1283 
1284 			// optname=<possible_values>
1285 			str_append_str(&dest, optmap[j].name);
1286 			str_append_str(&dest, "=<");
1287 
1288 			if (optmap[j].type == OPTMAP_TYPE_LZMA_PRESET) {
1289 				// LZMA1/2 preset has its custom help string.
1290 				str_append_str(&dest, LZMA12_PRESET_STR);
1291 			} else if (optmap[j].flags
1292 					& OPTMAP_USE_NAME_VALUE_MAP) {
1293 				// Separate the possible option values by "|".
1294 				const name_value_map *m = optmap[j].u.map;
1295 				for (size_t k = 0; m[k].name[0] != '\0'; ++k) {
1296 					if (k > 0)
1297 						str_append_str(&dest, "|");
1298 
1299 					str_append_str(&dest, m[k].name);
1300 				}
1301 			} else {
1302 				// Integer range is shown as min-max.
1303 				const bool use_byte_suffix = optmap[j].flags
1304 						& OPTMAP_USE_BYTE_SUFFIX;
1305 				str_append_u32(&dest, optmap[j].u.range.min,
1306 						use_byte_suffix);
1307 				str_append_str(&dest, "-");
1308 				str_append_u32(&dest, optmap[j].u.range.max,
1309 						use_byte_suffix);
1310 			}
1311 
1312 			str_append_str(&dest, ">");
1313 		}
1314 	}
1315 
1316 	// If no filters were added to the string then it must be because
1317 	// the caller provided an unsupported Filter ID.
1318 	if (!first_filter_printed) {
1319 		str_free(&dest, allocator);
1320 		return LZMA_OPTIONS_ERROR;
1321 	}
1322 
1323 	return str_finish(output_str, &dest, allocator);
1324 }
1325