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