1 /*-
2  * Copyright (c) 2011 Michihiro NAKAJIMA
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #include "test.h"
26 __FBSDID("$FreeBSD");
27 
28 #include <locale.h>
29 
30 static void
31 test_read_format_ustar_filename_eucJP_UTF8(const char *refname)
32 {
33 	struct archive *a;
34 	struct archive_entry *ae;
35 
36 	/*
37 	 * Read eucJP filename in en_US.UTF-8 with "hdrcharset=eucJP" option.
38 	 */
39 	if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
40 		skipping("en_US.UTF-8 locale not available on this system.");
41 		return;
42 	}
43 
44 	assert((a = archive_read_new()) != NULL);
45 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
46 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
47 	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) {
48 		skipping("This system cannot convert character-set"
49 		    " from eucJP to UTF-8.");
50 		goto cleanup;
51 	}
52 	assertEqualIntA(a, ARCHIVE_OK,
53 	    archive_read_open_filename(a, refname, 10240));
54 
55 	/* Verify regular file. */
56 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
57 	assertEqualString("\xe6\xbc\xa2\xe5\xad\x97.txt",
58 	    archive_entry_pathname(ae));
59 	assertEqualInt(8, archive_entry_size(ae));
60 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
61 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
62 
63 	/* Verify regular file. */
64 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
65 	assertEqualString("\xe8\xa1\xa8.txt", archive_entry_pathname(ae));
66 	assertEqualInt(4, archive_entry_size(ae));
67 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
68 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
69 
70 
71 	/* End of archive. */
72 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
73 
74 	/* Verify archive format. */
75 	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
76 	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
77 
78 	/* Close the archive. */
79 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
80 cleanup:
81 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
82 }
83 
84 static void
85 test_read_format_ustar_filename_CP866_KOI8R(const char *refname)
86 {
87 	struct archive *a;
88 	struct archive_entry *ae;
89 
90 	/*
91 	 * Read CP866 filename in ru_RU.KOI8-R with "hdrcharset=CP866" option.
92 	 */
93 	if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") &&
94 	    NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
95 		skipping("ru_RU.KOI8-R locale not available on this system.");
96 		return;
97 	}
98 
99 	assert((a = archive_read_new()) != NULL);
100 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
101 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
102 	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
103 		skipping("This system cannot convert character-set"
104 		    " from CP866 to KOI8-R.");
105 		goto cleanup;
106 	}
107 	assertEqualIntA(a, ARCHIVE_OK,
108 	    archive_read_open_filename(a, refname, 10240));
109 
110 	/* Verify regular file. */
111 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
112 	assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4",
113 	    archive_entry_pathname(ae));
114 	assertEqualInt(6, archive_entry_size(ae));
115 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
116 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
117 
118 	/* Verify regular file. */
119 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
120 	assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4",
121 	    archive_entry_pathname(ae));
122 	assertEqualInt(6, archive_entry_size(ae));
123 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
124 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
125 
126 	/* End of archive. */
127 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
128 
129 	/* Verify archive format. */
130 	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
131 	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
132 
133 	/* Close the archive. */
134 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
135 cleanup:
136 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
137 }
138 
139 static void
140 test_read_format_ustar_filename_CP866_UTF8(const char *refname)
141 {
142 	struct archive *a;
143 	struct archive_entry *ae;
144 
145 	/*
146 	 * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option.
147 	 */
148 	if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
149 		skipping("en_US.UTF-8 locale not available on this system.");
150 		return;
151 	}
152 
153 	assert((a = archive_read_new()) != NULL);
154 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
155 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
156 	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
157 		skipping("This system cannot convert character-set"
158 		    " from CP866 to UTF-8.");
159 		goto cleanup;
160 	}
161 	assertEqualIntA(a, ARCHIVE_OK,
162 	    archive_read_open_filename(a, refname, 10240));
163 
164 	/* Verify regular file. */
165 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
166 	assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
167 	    archive_entry_pathname(ae));
168 	assertEqualInt(6, archive_entry_size(ae));
169 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
170 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
171 
172 	/* Verify regular file. */
173 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
174 	assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
175 	    archive_entry_pathname(ae));
176 	assertEqualInt(6, archive_entry_size(ae));
177 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
178 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
179 
180 
181 	/* End of archive. */
182 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
183 
184 	/* Verify archive format. */
185 	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
186 	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
187 
188 	/* Close the archive. */
189 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
190 cleanup:
191 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
192 }
193 
194 static void
195 test_read_format_ustar_filename_KOI8R_CP866(const char *refname)
196 {
197 	struct archive *a;
198 	struct archive_entry *ae;
199 
200 	/*
201 	 * Read KOI8-R filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option.
202 	 */
203 	if (NULL == setlocale(LC_ALL, "Russian_Russia.866") &&
204 	    NULL == setlocale(LC_ALL, "ru_RU.CP866")) {
205 		skipping("ru_RU.CP866 locale not available on this system.");
206 		return;
207 	}
208 
209 	assert((a = archive_read_new()) != NULL);
210 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
211 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
212 	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
213 		skipping("This system cannot convert character-set"
214 		    " from KOI8-R to CP866.");
215 		goto cleanup;
216 	}
217 	assertEqualIntA(a, ARCHIVE_OK,
218 	    archive_read_open_filename(a, refname, 10240));
219 
220 	/* Verify regular file. */
221 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
222 	assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2",
223 	    archive_entry_pathname(ae));
224 	assertEqualInt(6, archive_entry_size(ae));
225 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
226 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
227 
228 	/* Verify regular file. */
229 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
230 	assertEqualString("\x8f\x90\x88\x82\x85\x92",
231 	    archive_entry_pathname(ae));
232 	assertEqualInt(6, archive_entry_size(ae));
233 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
234 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
235 
236 
237 	/* End of archive. */
238 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
239 
240 	/* Verify archive format. */
241 	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
242 	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
243 
244 	/* Close the archive. */
245 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
246 cleanup:
247 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
248 }
249 
250 static void
251 test_read_format_ustar_filename_KOI8R_UTF8(const char *refname)
252 {
253 	struct archive *a;
254 	struct archive_entry *ae;
255 
256 	/*
257 	 * Read KOI8-R filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option.
258 	 */
259 	if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
260 		skipping("en_US.UTF-8 locale not available on this system.");
261 		return;
262 	}
263 
264 	assert((a = archive_read_new()) != NULL);
265 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
266 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
267 	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
268 		skipping("This system cannot convert character-set"
269 		    " from KOI8-R to UTF-8.");
270 		goto cleanup;
271 	}
272 	assertEqualIntA(a, ARCHIVE_OK,
273 	    archive_read_open_filename(a, refname, 10240));
274 
275 	/* Verify regular file. */
276 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
277 	assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
278 	    archive_entry_pathname(ae));
279 	assertEqualInt(6, archive_entry_size(ae));
280 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
281 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
282 
283 	/* Verify regular file. */
284 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
285 	assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
286 	    archive_entry_pathname(ae));
287 	assertEqualInt(6, archive_entry_size(ae));
288 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
289 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
290 
291 
292 	/* End of archive. */
293 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
294 
295 	/* Verify archive format. */
296 	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
297 	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
298 
299 	/* Close the archive. */
300 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
301 cleanup:
302 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
303 }
304 
305 static void
306 test_read_format_ustar_filename_eucJP_CP932(const char *refname)
307 {
308 	struct archive *a;
309 	struct archive_entry *ae;
310 
311 	/*
312 	 * Read eucJP filename in CP932/SJIS with "hdrcharset=eucJP" option.
313 	 */
314 	if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
315 	    NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
316 		skipping("CP932 locale not available on this system.");
317 		return;
318 	}
319 
320 	assert((a = archive_read_new()) != NULL);
321 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
322 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
323 	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) {
324 		skipping("This system cannot convert character-set"
325 		    " from eucJP.");
326 		goto cleanup;
327 	}
328 	assertEqualIntA(a, ARCHIVE_OK,
329 	    archive_read_open_filename(a, refname, 10240));
330 
331 	/* Verify regular file. */
332 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
333 	assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae));
334 	assertEqualInt(8, archive_entry_size(ae));
335 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
336 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
337 
338 	/* Verify regular file. */
339 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
340 	assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae));
341 	assertEqualInt(4, archive_entry_size(ae));
342 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
343 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
344 
345 
346 	/* End of archive. */
347 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
348 
349 	/* Verify archive format. */
350 	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
351 	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
352 
353 	/* Close the archive. */
354 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
355 cleanup:
356 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
357 }
358 
359 static void
360 test_read_format_ustar_filename_CP866_CP1251(const char *refname)
361 {
362 	struct archive *a;
363 	struct archive_entry *ae;
364 
365 	/*
366 	 * Read CP866 filename in CP1251 with "hdrcharset=CP866" option.
367 	 */
368 	if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
369 	    NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
370 		skipping("CP1251 locale not available on this system.");
371 		return;
372 	}
373 
374 	assert((a = archive_read_new()) != NULL);
375 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
376 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
377 	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
378 		skipping("This system cannot convert character-set"
379 		    " from CP866 to CP1251.");
380 		goto cleanup;
381 	}
382 	assertEqualIntA(a, ARCHIVE_OK,
383 	    archive_read_open_filename(a, refname, 10240));
384 
385 	/* Verify regular file. */
386 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
387 	assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
388 	    archive_entry_pathname(ae));
389 	assertEqualInt(6, archive_entry_size(ae));
390 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
391 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
392 
393 	/* Verify regular file. */
394 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
395 	assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
396 	    archive_entry_pathname(ae));
397 	assertEqualInt(6, archive_entry_size(ae));
398 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
399 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
400 
401 
402 	/* End of archive. */
403 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
404 
405 	/* Verify archive format. */
406 	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
407 	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
408 
409 	/* Close the archive. */
410 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
411 cleanup:
412 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
413 }
414 
415 /*
416  * This test only for Windows platform because other archiver
417  * applications on Windows translate CP1251 filenames into CP866
418  * filenames and store it in the ustar file and so we should read
419  * it by default on Windows.
420  */
421 static void
422 test_read_format_ustar_filename_CP866_CP1251_win(const char *refname)
423 {
424 	struct archive *a;
425 	struct archive_entry *ae;
426 
427 	/*
428 	 * Read CP866 filename in CP1251 without "hdrcharset=CP866" option.
429 	 */
430 	if (NULL == setlocale(LC_ALL, "Russian_Russia")) {
431 		skipping("Russian_Russia locale not available on this system.");
432 		return;
433 	}
434 
435 	assert((a = archive_read_new()) != NULL);
436 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
437 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
438 	assertEqualIntA(a, ARCHIVE_OK,
439 	    archive_read_open_filename(a, refname, 10240));
440 
441 	/* Verify regular file. */
442 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
443 	assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
444 	    archive_entry_pathname(ae));
445 	assertEqualInt(6, archive_entry_size(ae));
446 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
447 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
448 
449 	/* Verify regular file. */
450 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
451 	assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
452 	    archive_entry_pathname(ae));
453 	assertEqualInt(6, archive_entry_size(ae));
454 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
455 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
456 
457 
458 	/* End of archive. */
459 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
460 
461 	/* Verify archive format. */
462 	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
463 	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
464 
465 	/* Close the archive. */
466 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
467 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
468 }
469 
470 static void
471 test_read_format_ustar_filename_KOI8R_CP1251(const char *refname)
472 {
473 	struct archive *a;
474 	struct archive_entry *ae;
475 
476 	/*
477 	 * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option.
478 	 */
479 	if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
480 	    NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
481 		skipping("CP1251 locale not available on this system.");
482 		return;
483 	}
484 
485 	assert((a = archive_read_new()) != NULL);
486 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
487 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
488 	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
489 		skipping("This system cannot convert character-set"
490 		    " from KOI8-R to CP1251.");
491 		goto cleanup;
492 	}
493 	assertEqualIntA(a, ARCHIVE_OK,
494 	    archive_read_open_filename(a, refname, 10240));
495 
496 	/* Verify regular file. */
497 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
498 	assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
499 	    archive_entry_pathname(ae));
500 	assertEqualInt(6, archive_entry_size(ae));
501 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
502 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
503 
504 	/* Verify regular file. */
505 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
506 	assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
507 	    archive_entry_pathname(ae));
508 	assertEqualInt(6, archive_entry_size(ae));
509 	assertEqualInt(archive_entry_is_encrypted(ae), 0);
510 	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
511 
512 
513 	/* End of archive. */
514 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
515 
516 	/* Verify archive format. */
517 	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
518 	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));
519 
520 	/* Close the archive. */
521 	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
522 cleanup:
523 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
524 }
525 
526 
527 DEFINE_TEST(test_read_format_ustar_filename)
528 {
529 	const char *refname1 = "test_read_format_ustar_filename_eucjp.tar.Z";
530 	const char *refname2 = "test_read_format_ustar_filename_cp866.tar.Z";
531 	const char *refname3 = "test_read_format_ustar_filename_koi8r.tar.Z";
532 
533 	extract_reference_file(refname1);
534 	test_read_format_ustar_filename_eucJP_UTF8(refname1);
535 	test_read_format_ustar_filename_eucJP_CP932(refname1);
536 
537 	extract_reference_file(refname2);
538 	test_read_format_ustar_filename_CP866_KOI8R(refname2);
539 	test_read_format_ustar_filename_CP866_UTF8(refname2);
540 	test_read_format_ustar_filename_CP866_CP1251(refname2);
541 	test_read_format_ustar_filename_CP866_CP1251_win(refname2);
542 
543 	extract_reference_file(refname3);
544 	test_read_format_ustar_filename_KOI8R_CP866(refname3);
545 	test_read_format_ustar_filename_KOI8R_UTF8(refname3);
546 	test_read_format_ustar_filename_KOI8R_CP1251(refname3);
547 }
548