xref: /freebsd/contrib/libarchive/libarchive/test/test_read_format_tar_mac_metadata.c (revision 2e113ef82465598b8c26e0ca415fbe90677fbd47)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2025 Zhaofeng Li
5  * All rights reserved.
6  */
7 #include "test.h"
8 
DEFINE_TEST(test_read_format_tar_mac_metadata)9 DEFINE_TEST(test_read_format_tar_mac_metadata)
10 {
11 	/*
12 	 This test tar file is crafted with two files in a specific order:
13 
14 	 1. A ._-prefixed file with pax header containing the path attribute.
15 	 2. A file with a pax header but without the path attribute.
16 
17 	 It's designed to trigger the case encountered in:
18 	 <https://github.com/libarchive/libarchive/pull/2636>
19 
20 	 GNU tar is required to reproduce this tar file:
21 
22 	 ```sh
23 	 NAME1="._101_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
24 	 NAME2="goodname"
25 	 OUT="test_read_format_tar_mac_metadata_1.tar"
26 
27 	 echo "content of badname" >"${NAME1}"
28 	 echo "content of goodname" >"${NAME2}"
29 
30 	 rm -f "${OUT}"
31 	 gnutar \
32 	 	--mtime="@0" \
33 	 	--owner=0 --group=0 --numeric-owner \
34 	 	--pax-option=exthdr.name=%d/PaxHeaders/%f,atime:=0,ctime:=0,foo:=bar \
35 	 	--format=pax \
36 	 	-cf "${OUT}" \
37 	 	"${NAME1}" \
38 	 	"${NAME2}"
39 	 uuencode "${OUT}" "${OUT}" >"${OUT}.uu"
40 
41 	 sha256sum "${OUT}"
42 	 sha256sum "${OUT}.uu"
43 	 ```
44 	*/
45 	const char *refname = "test_read_format_tar_mac_metadata_1.tar";
46 	char *p;
47 	size_t s;
48 	struct archive *a;
49 	struct archive_entry *ae;
50 
51 	/*
52 	 * This is not a valid AppleDouble metadata file. It is merely to test that
53 	 * the correct bytes are read.
54 	 */
55 	const unsigned char appledouble[] = {
56 		0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x62,
57 		0x61, 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x0a
58 	};
59 
60 	extract_reference_file(refname);
61 	p = slurpfile(&s, "%s", refname);
62 
63 	assert((a = archive_read_new()) != NULL);
64 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_tar(a));
65 	assertEqualIntA(a, ARCHIVE_OK, archive_read_set_option(a, "tar", "mac-ext", "1"));
66 	assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));
67 
68 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
69 
70 	/* Correct name and metadata bytes */
71 	assertEqualString("goodname", archive_entry_pathname(ae));
72 
73 	const void *metadata = archive_entry_mac_metadata(ae, &s);
74 	if (assert(metadata != NULL)) {
75 		assertEqualMem(metadata, appledouble,
76 			sizeof(appledouble));
77 	}
78 
79 	/* ... and nothing else */
80 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
81 	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
82 	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
83 
84 	free(p);
85 }
86