xref: /aosp_15_r20/external/xz-embedded/userspace/bytetest.c (revision d2c16535d139cb185e89120452531bba6b36d3c6)
1 // SPDX-License-Identifier: 0BSD
2 
3 /*
4  * Lazy test for the case when the output size is known
5  *
6  * Author: Lasse Collin <[email protected]>
7  */
8 
9 #include <stdbool.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include "xz.h"
14 
15 static uint8_t in[1];
16 static uint8_t out[BUFSIZ];
17 
main(int argc,char ** argv)18 int main(int argc, char **argv)
19 {
20 	struct xz_buf b;
21 	struct xz_dec *s;
22 	enum xz_ret ret;
23 	const char *msg;
24 	size_t uncomp_size;
25 
26 	if (argc != 2) {
27 		fputs("Give uncompressed size as the argument\n", stderr);
28 		return 1;
29 	}
30 
31 	uncomp_size = atoi(argv[1]);
32 
33 	xz_crc32_init();
34 
35 	/*
36 	 * Support up to 64 MiB dictionary. The actually needed memory
37 	 * is allocated once the headers have been parsed.
38 	 */
39 	s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
40 	if (s == NULL) {
41 		msg = "Memory allocation failed\n";
42 		goto error;
43 	}
44 
45 	b.in = in;
46 	b.in_pos = 0;
47 	b.in_size = 0;
48 	b.out = out;
49 	b.out_pos = 0;
50 	b.out_size = uncomp_size < BUFSIZ ? uncomp_size : BUFSIZ;
51 
52 	while (true) {
53 		if (b.in_pos == b.in_size) {
54 			b.in_size = fread(in, 1, sizeof(in), stdin);
55 			b.in_pos = 0;
56 		}
57 
58 		ret = xz_dec_run(s, &b);
59 
60 		if (b.out_pos == sizeof(out)) {
61 			if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {
62 				msg = "Write error\n";
63 				goto error;
64 			}
65 
66 			uncomp_size -= b.out_pos;
67 			b.out_pos = 0;
68 			b.out_size = uncomp_size < BUFSIZ
69 					? uncomp_size : BUFSIZ;
70 		}
71 
72 		if (ret == XZ_OK)
73 			continue;
74 
75 #ifdef XZ_DEC_ANY_CHECK
76 		if (ret == XZ_UNSUPPORTED_CHECK) {
77 			fputs(argv[0], stderr);
78 			fputs(": ", stderr);
79 			fputs("Unsupported check; not verifying "
80 					"file integrity\n", stderr);
81 			continue;
82 		}
83 #endif
84 
85 		if (uncomp_size != b.out_pos) {
86 			msg = "Uncompressed size doesn't match\n";
87 			goto error;
88 		}
89 
90 		if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos
91 				|| fclose(stdout)) {
92 			msg = "Write error\n";
93 			goto error;
94 		}
95 
96 		switch (ret) {
97 		case XZ_STREAM_END:
98 			xz_dec_end(s);
99 			return 0;
100 
101 		case XZ_MEM_ERROR:
102 			msg = "Memory allocation failed\n";
103 			goto error;
104 
105 		case XZ_MEMLIMIT_ERROR:
106 			msg = "Memory usage limit reached\n";
107 			goto error;
108 
109 		case XZ_FORMAT_ERROR:
110 			msg = "Not a .xz file\n";
111 			goto error;
112 
113 		case XZ_OPTIONS_ERROR:
114 			msg = "Unsupported options in the .xz headers\n";
115 			goto error;
116 
117 		case XZ_DATA_ERROR:
118 		case XZ_BUF_ERROR:
119 			msg = "File is corrupt\n";
120 			goto error;
121 
122 		default:
123 			msg = "Bug!\n";
124 			goto error;
125 		}
126 	}
127 
128 error:
129 	xz_dec_end(s);
130 	fputs(argv[0], stderr);
131 	fputs(": ", stderr);
132 	fputs(msg, stderr);
133 	return 1;
134 }
135