1/*-
2 * Copyright (c) 2003-2007 Tim Kientzle
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/*
29 * Each of these archives is a short archive with a single entry.  The
30 * corresponding verify function verifies the entry structure returned
31 * from libarchive is what it should be.  The support functions pad with
32 * lots of zeros, so we can trim trailing zero bytes from each hardcoded
33 * archive to save space.
34 *
35 * The naming here follows the tar file type flags.  E.g. '1' is a hardlink,
36 * '2' is a symlink, '5' is a dir, etc.
37 */
38
39/* Empty archive. */
40static unsigned char archiveEmpty[] = {
41	/* 512 zero bytes */
42	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
43	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
44	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
45	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
46
47	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
48	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
49	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
50	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
51
52	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
53	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
54	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
55	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
56
57	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
58	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
59	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
60	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
61};
62
63static void verifyEmpty(void)
64{
65	struct archive_entry *ae;
66	struct archive *a;
67
68	assert((a = archive_read_new()) != NULL);
69	assertA(0 == archive_read_support_filter_all(a));
70	assertA(0 == archive_read_support_format_all(a));
71	assertA(0 == archive_read_open_memory(a, archiveEmpty, 512));
72	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
73	assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
74	assertEqualString(archive_filter_name(a, 0), "none");
75	failure("512 zero bytes should be recognized as a tar archive.");
76	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR);
77	assertEqualInt(archive_entry_is_encrypted(ae), 0);
78	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
79
80	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
81	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
82}
83
84/* Single entry with a hardlink. */
85static unsigned char archive1[] = {
86'h','a','r','d','l','i','n','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
880,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0',
89'0','6','4','4',' ',0,'0','0','1','7','5','0',' ',0,'0','0','1','7','5','0',
90' ',0,'0','0','0','0','0','0','0','0','0','0','0',' ','1','0','6','4','6',
91'0','5','2','6','6','2',' ','0','1','3','0','5','7',0,' ','1','f','i','l',
92'e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
930,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
940,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,'0',
95'0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
96't','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0',
97'0','0','0','0','0',' ',0,'0','0','0','0','0','0',' '};
98
99static void verify1(struct archive_entry *ae)
100{
101	/* A hardlink is not a symlink. */
102	assert(archive_entry_filetype(ae) != AE_IFLNK);
103	/* Nor is it a directory. */
104	assert(archive_entry_filetype(ae) != AE_IFDIR);
105	assertEqualInt(archive_entry_mode(ae) & 0777, 0644);
106	assertEqualInt(archive_entry_uid(ae), 1000);
107	assertEqualInt(archive_entry_gid(ae), 1000);
108	assertEqualString(archive_entry_uname(ae), "tim");
109	assertEqualString(archive_entry_gname(ae), "tim");
110	assertEqualString(archive_entry_pathname(ae), "hardlink");
111	assertEqualString(archive_entry_hardlink(ae), "file");
112	assert(archive_entry_symlink(ae) == NULL);
113	assertEqualInt(archive_entry_mtime(ae), 1184388530);
114}
115
116/* Verify that symlinks are read correctly. */
117static unsigned char archive2[] = {
118's','y','m','l','i','n','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0',
121'0','0','7','5','5',' ','0','0','0','1','7','5','0',' ','0','0','0','1','7',
122'5','0',' ','0','0','0','0','0','0','0','0','0','0','0',' ','1','0','6','4',
123'6','0','5','4','1','0','1',' ','0','0','1','3','3','2','3',' ','2','f','i',
124'l','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
127'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1280,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
129'0','0','0','0','0','0','0',' ','0','0','0','0','0','0','0',' '};
130
131static void verify2(struct archive_entry *ae)
132{
133	assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
134	assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
135	assertEqualInt(archive_entry_uid(ae), 1000);
136	assertEqualInt(archive_entry_gid(ae), 1000);
137	assertEqualString(archive_entry_uname(ae), "tim");
138	assertEqualString(archive_entry_gname(ae), "tim");
139	assertEqualString(archive_entry_pathname(ae), "symlink");
140	assertEqualString(archive_entry_symlink(ae), "file");
141	assert(archive_entry_hardlink(ae) == NULL);
142	assertEqualInt(archive_entry_mtime(ae), 1184389185);
143}
144
145/* Character device node. */
146static unsigned char archive3[] = {
147'd','e','v','c','h','a','r',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1490,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0',
150'0','0','7','5','5',' ','0','0','0','1','7','5','0',' ','0','0','0','1','7',
151'5','0',' ','0','0','0','0','0','0','0','0','0','0','0',' ','1','0','6','4',
152'6','0','5','4','1','0','1',' ','0','0','1','2','4','1','2',' ','3',0,0,
1530,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1540,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
156'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1570,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
158'0','0','0','0','0','0','0',' ','0','0','0','0','0','0','0',' '};
159
160static void verify3(struct archive_entry *ae)
161{
162	assertEqualInt(archive_entry_filetype(ae), AE_IFCHR);
163	assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
164	assertEqualInt(archive_entry_uid(ae), 1000);
165	assertEqualInt(archive_entry_gid(ae), 1000);
166	assertEqualString(archive_entry_uname(ae), "tim");
167	assertEqualString(archive_entry_gname(ae), "tim");
168	assertEqualString(archive_entry_pathname(ae), "devchar");
169	assert(archive_entry_symlink(ae) == NULL);
170	assert(archive_entry_hardlink(ae) == NULL);
171	assertEqualInt(archive_entry_mtime(ae), 1184389185);
172}
173
174/* Block device node. */
175static unsigned char archive4[] = {
176'd','e','v','b','l','o','c','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1770,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0',
179'0','0','7','5','5',' ','0','0','0','1','7','5','0',' ','0','0','0','1','7',
180'5','0',' ','0','0','0','0','0','0','0','0','0','0','0',' ','1','0','6','4',
181'6','0','5','4','1','0','1',' ','0','0','1','2','5','7','0',' ','4',0,0,
1820,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1830,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1840,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
185'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1860,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
187'0','0','0','0','0','0','0',' ','0','0','0','0','0','0','0',' '};
188
189static void verify4(struct archive_entry *ae)
190{
191	assertEqualInt(archive_entry_filetype(ae), AE_IFBLK);
192	assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
193	assertEqualInt(archive_entry_uid(ae), 1000);
194	assertEqualInt(archive_entry_gid(ae), 1000);
195	assertEqualString(archive_entry_uname(ae), "tim");
196	assertEqualString(archive_entry_gname(ae), "tim");
197	assertEqualString(archive_entry_pathname(ae), "devblock");
198	assert(archive_entry_symlink(ae) == NULL);
199	assert(archive_entry_hardlink(ae) == NULL);
200	assertEqualInt(archive_entry_mtime(ae), 1184389185);
201}
202
203/* Directory. */
204static unsigned char archive5[] = {
205'.',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2060,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2070,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0','0',
208'7','5','5',' ',0,'0','0','1','7','5','0',' ',0,'0','0','1','7','5','0',
209' ',0,'0','0','0','0','0','0','0','0','0','0','0',' ','1','0','3','3',
210'4','0','4','1','7','3','6',' ','0','1','0','5','6','1',0,' ','5',0,0,0,
2110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
214'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2150,0,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2160,0,'0','0','0','0','0','0',' ',0,'0','0','0','0','0','0',' '};
217
218static void verify5(struct archive_entry *ae)
219{
220	assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
221	assertEqualInt(archive_entry_mtime(ae), 1131430878);
222	assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
223	assertEqualInt(archive_entry_uid(ae), 1000);
224	assertEqualInt(archive_entry_gid(ae), 1000);
225	assertEqualString(archive_entry_uname(ae), "tim");
226	assertEqualString(archive_entry_gname(ae), "tim");
227}
228
229/* fifo */
230static unsigned char archive6[] = {
231'f','i','f','o',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2320,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2330,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0',
234'0','0','7','5','5',' ','0','0','0','1','7','5','0',' ','0','0','0','1','7',
235'5','0',' ','0','0','0','0','0','0','0','0','0','0','0',' ','1','0','6','4',
236'6','0','5','4','1','0','1',' ','0','0','1','1','7','2','4',' ','6',0,0,
2370,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2380,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',0,
240'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2410,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
242'0','0','0','0','0','0','0',' ','0','0','0','0','0','0','0',' '};
243
244static void verify6(struct archive_entry *ae)
245{
246	assertEqualInt(archive_entry_filetype(ae), AE_IFIFO);
247	assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
248	assertEqualInt(archive_entry_uid(ae), 1000);
249	assertEqualInt(archive_entry_gid(ae), 1000);
250	assertEqualString(archive_entry_uname(ae), "tim");
251	assertEqualString(archive_entry_gname(ae), "tim");
252	assertEqualString(archive_entry_pathname(ae), "fifo");
253	assert(archive_entry_symlink(ae) == NULL);
254	assert(archive_entry_hardlink(ae) == NULL);
255	assertEqualInt(archive_entry_mtime(ae), 1184389185);
256}
257
258/* GNU long link name */
259static unsigned char archiveK[] = {
260'.','/','.','/','@','L','o','n','g','L','i','n','k',0,0,0,0,0,0,0,0,0,0,0,
2610,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2620,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2630,0,'0','0','0','0','0','0','0',0,'0','0','0','0','0','0','0',0,'0','0','0',
264'0','0','0','0',0,'0','0','0','0','0','0','0','0','6','6','6',0,'0','0','0',
265'0','0','0','0','0','0','0','0',0,'0','1','1','7','1','5',0,' ','K',0,0,0,
2660,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2670,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u','s','t','a','r',' ',' ',
2690,'r','o','o','t',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
270'w','h','e','e','l',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2710,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2720,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2730,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2740,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'t',
276'h','i','s','_','i','s','_','a','_','v','e','r','y','_','l','o','n','g','_',
277's','y','m','l','i','n','k','_','b','o','d','y','_','a','b','c','d','e','f',
278'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y',
279'z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
280'r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i',
281'j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a',
282'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t',
283'u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l',
284'm','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d',
285'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w',
286'x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
287'p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g',
288'h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
289'_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
290's','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j',
291'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b',
292'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u',
293'v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m',
294'n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e',
295'f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x',
296'y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p',
297'q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g','h',
298'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',0,
2990,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
301's','y','m','l','i','n','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3020,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3030,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','1',
304'2','0','7','5','5',0,'0','0','0','1','7','5','0',0,'0','0','0','1','7','5',
305'0',0,'0','0','0','0','0','0','0','0','0','0','0',0,'1','0','6','4','6','0',
306'5','6','7','7','0',0,'0','3','5','4','4','7',0,' ','2','t','h','i','s','_',
307'i','s','_','a','_','v','e','r','y','_','l','o','n','g','_','s','y','m','l',
308'i','n','k','_','b','o','d','y','_','a','b','c','d','e','f','g','h','i','j',
309'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b',
310'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u',
311'v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l',0,
312'u','s','t','a','r',' ',' ',0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3130,0,0,0,0,0,0,0,0,0,0,0,0,'t','i','m'};
314
315static void verifyK(struct archive_entry *ae)
316{
317	assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
318	assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
319	assertEqualInt(archive_entry_uid(ae), 1000);
320	assertEqualInt(archive_entry_gid(ae), 1000);
321	assertEqualString(archive_entry_uname(ae), "tim");
322	assertEqualString(archive_entry_gname(ae), "tim");
323	assertEqualString(archive_entry_pathname(ae), "symlink");
324	assertEqualString(archive_entry_symlink(ae),
325	    "this_is_a_very_long_symlink_body_abcdefghijklmnopqrstuvwxyz_"
326	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
327	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
328	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
329	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
330	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
331	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
332	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz");
333	assert(archive_entry_hardlink(ae) == NULL);
334	assertEqualInt(archive_entry_mtime(ae), 1184390648);
335}
336
337/* TODO: GNU long name */
338
339/* TODO: Solaris ACL */
340
341/* Pax extended long link name */
342static unsigned char archivexL[] = {
343'.','/','P','a','x','H','e','a','d','e','r','s','.','8','6','9','7','5','/',
344's','y','m','l','i','n','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3450,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3460,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0','0','0','6','4','4',0,'0','0','0','1',
347'7','5','0',0,'0','0','0','1','7','5','0',0,'0','0','0','0','0','0','0','0',
348'7','5','3',0,'1','0','6','4','6','0','5','7','6','1','1',0,'0','1','3','7',
349'1','4',0,' ','x',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3510,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'u',
352's','t','a','r',0,'0','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3530,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3540,0,0,'0','0','0','0','0','0','0',0,'0','0','0','0','0','0','0',0,0,0,0,0,
3550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3560,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3570,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3590,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'4','5','1',' ','l','i','n','k','p','a','t',
360'h','=','t','h','i','s','_','i','s','_','a','_','v','e','r','y','_','l','o',
361'n','g','_','s','y','m','l','i','n','k','_','b','o','d','y','_','a','b','c',
362'd','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
363'w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n',
364'o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f',
365'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y',
366'z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
367'r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i',
368'j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a',
369'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t',
370'u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l',
371'm','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d',
372'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w',
373'x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
374'p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g',
375'h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
376'_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
377's','t','u','v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j',
378'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b',
379'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u',
380'v','w','x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m',
381'n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d','e',
382'f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x',
383'y','z',10,'2','0',' ','a','t','i','m','e','=','1','1','8','4','3','9','1',
384'0','2','5',10,'2','0',' ','c','t','i','m','e','=','1','1','8','4','3','9',
385'0','6','4','8',10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'s','y','m',
386'l','i','n','k',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3880,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'0','0','0','0','7',
389'5','5',0,'0','0','0','1','7','5','0',0,'0','0','0','1','7','5','0',0,'0',
390'0','0','0','0','0','0','0','0','0','0',0,'1','0','6','4','6','0','5','6',
391'7','7','0',0,'0','3','7','1','2','1',0,' ','2','t','h','i','s','_','i','s',
392'_','a','_','v','e','r','y','_','l','o','n','g','_','s','y','m','l','i','n',
393'k','_','b','o','d','y','_','a','b','c','d','e','f','g','h','i','j','k','l',
394'm','n','o','p','q','r','s','t','u','v','w','x','y','z','_','a','b','c','d',
395'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w',
396'x','y','z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','u','s',
397't','a','r',0,'0','0','t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3980,0,0,0,0,0,0,0,0,'t','i','m',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3990,0,0,0,0,0,0,'0','0','0','0','0','0','0',0,'0','0','0','0','0','0','0'};
400
401static void verifyxL(struct archive_entry *ae)
402{
403	assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
404	assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
405	assertEqualInt(archive_entry_uid(ae), 1000);
406	assertEqualInt(archive_entry_gid(ae), 1000);
407	assertEqualString(archive_entry_uname(ae), "tim");
408	assertEqualString(archive_entry_gname(ae), "tim");
409	assertEqualString(archive_entry_pathname(ae), "symlink");
410	assertEqualString(archive_entry_symlink(ae),
411	    "this_is_a_very_long_symlink_body_abcdefghijklmnopqrstuvwxyz_"
412	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
413	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
414	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
415	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
416	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
417	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_"
418	    "abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz");
419	assert(archive_entry_hardlink(ae) == NULL);
420	assertEqualInt(archive_entry_mtime(ae), 1184390648);
421}
422
423
424/* TODO: Any other types of headers? */
425
426static void verify(unsigned char *d, size_t s,
427    void (*f)(struct archive_entry *),
428    int compression, int format)
429{
430	struct archive_entry *ae;
431	struct archive *a;
432	unsigned char *buff = malloc(100000);
433
434	memcpy(buff, d, s);
435	memset(buff + s, 0, 2048);
436
437	assert((a = archive_read_new()) != NULL);
438	assertA(0 == archive_read_support_filter_all(a));
439	assertA(0 == archive_read_support_format_all(a));
440	assertA(0 == archive_read_open_memory(a, buff, s + 1024));
441	assertA(0 == archive_read_next_header(a, &ae));
442	assertEqualInt(archive_filter_code(a, 0), compression);
443	assertEqualInt(archive_format(a), format);
444	assertEqualInt(archive_entry_is_encrypted(ae), 0);
445	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);
446
447	/* Verify the only entry. */
448	f(ae);
449
450	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
451	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
452	free(buff);
453}
454
455DEFINE_TEST(test_read_format_tar)
456{
457	verifyEmpty();
458	verify(archive1, sizeof(archive1), verify1,
459	    ARCHIVE_FILTER_NONE, ARCHIVE_FORMAT_TAR_USTAR);
460	verify(archive2, sizeof(archive2), verify2,
461	    ARCHIVE_FILTER_NONE, ARCHIVE_FORMAT_TAR_USTAR);
462	verify(archive3, sizeof(archive3), verify3,
463	    ARCHIVE_FILTER_NONE, ARCHIVE_FORMAT_TAR_USTAR);
464	verify(archive4, sizeof(archive4), verify4,
465	    ARCHIVE_FILTER_NONE, ARCHIVE_FORMAT_TAR_USTAR);
466	verify(archive5, sizeof(archive5), verify5,
467	    ARCHIVE_FILTER_NONE, ARCHIVE_FORMAT_TAR_USTAR);
468	verify(archive6, sizeof(archive6), verify6,
469	    ARCHIVE_FILTER_NONE, ARCHIVE_FORMAT_TAR_USTAR);
470	verify(archiveK, sizeof(archiveK), verifyK,
471	    ARCHIVE_FILTER_NONE, ARCHIVE_FORMAT_TAR_GNUTAR);
472	verify(archivexL, sizeof(archivexL), verifyxL,
473	    ARCHIVE_FILTER_NONE, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE);
474}
475
476
477