1*543adbedSBen Gras /*-
2*543adbedSBen Gras  * Copyright (c) 2003-2007 Tim Kientzle
3*543adbedSBen Gras  * All rights reserved.
4*543adbedSBen Gras  *
5*543adbedSBen Gras  * Redistribution and use in source and binary forms, with or without
6*543adbedSBen Gras  * modification, are permitted provided that the following conditions
7*543adbedSBen Gras  * are met:
8*543adbedSBen Gras  * 1. Redistributions of source code must retain the above copyright
9*543adbedSBen Gras  *    notice, this list of conditions and the following disclaimer.
10*543adbedSBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
11*543adbedSBen Gras  *    notice, this list of conditions and the following disclaimer in the
12*543adbedSBen Gras  *    documentation and/or other materials provided with the distribution.
13*543adbedSBen Gras  *
14*543adbedSBen Gras  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15*543adbedSBen Gras  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16*543adbedSBen Gras  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17*543adbedSBen Gras  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18*543adbedSBen Gras  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19*543adbedSBen Gras  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20*543adbedSBen Gras  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21*543adbedSBen Gras  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22*543adbedSBen Gras  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23*543adbedSBen Gras  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*543adbedSBen Gras  */
25*543adbedSBen Gras #include "test.h"
26*543adbedSBen Gras __FBSDID("$FreeBSD: src/lib/libarchive/test/test_link_resolver.c,v 1.2 2008/06/15 04:31:43 kientzle Exp $");
27*543adbedSBen Gras 
test_linkify_tar(void)28*543adbedSBen Gras static void test_linkify_tar(void)
29*543adbedSBen Gras {
30*543adbedSBen Gras 	struct archive_entry *entry, *e2;
31*543adbedSBen Gras 	struct archive_entry_linkresolver *resolver;
32*543adbedSBen Gras 
33*543adbedSBen Gras 	/* Initialize the resolver. */
34*543adbedSBen Gras 	assert(NULL != (resolver = archive_entry_linkresolver_new()));
35*543adbedSBen Gras 	archive_entry_linkresolver_set_strategy(resolver,
36*543adbedSBen Gras 	    ARCHIVE_FORMAT_TAR_USTAR);
37*543adbedSBen Gras 
38*543adbedSBen Gras 	/* Create an entry with only 1 link and try to linkify it. */
39*543adbedSBen Gras 	assert(NULL != (entry = archive_entry_new()));
40*543adbedSBen Gras 	archive_entry_set_pathname(entry, "test1");
41*543adbedSBen Gras 	archive_entry_set_ino(entry, 1);
42*543adbedSBen Gras 	archive_entry_set_dev(entry, 2);
43*543adbedSBen Gras 	archive_entry_set_nlink(entry, 1);
44*543adbedSBen Gras 	archive_entry_set_size(entry, 10);
45*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
46*543adbedSBen Gras 
47*543adbedSBen Gras 	/* Shouldn't have been changed. */
48*543adbedSBen Gras 	assert(e2 == NULL);
49*543adbedSBen Gras 	assertEqualInt(10, archive_entry_size(entry));
50*543adbedSBen Gras 	assertEqualString("test1", archive_entry_pathname(entry));
51*543adbedSBen Gras 
52*543adbedSBen Gras 	/* Now, try again with an entry that has 2 links. */
53*543adbedSBen Gras 	archive_entry_set_pathname(entry, "test2");
54*543adbedSBen Gras 	archive_entry_set_nlink(entry, 2);
55*543adbedSBen Gras 	archive_entry_set_ino(entry, 2);
56*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
57*543adbedSBen Gras 	/* Shouldn't be altered, since it wasn't seen before. */
58*543adbedSBen Gras 	assert(e2 == NULL);
59*543adbedSBen Gras 	assertEqualString("test2", archive_entry_pathname(entry));
60*543adbedSBen Gras 	assertEqualString(NULL, archive_entry_hardlink(entry));
61*543adbedSBen Gras 	assertEqualInt(10, archive_entry_size(entry));
62*543adbedSBen Gras 
63*543adbedSBen Gras 	/* Match again and make sure it does get altered. */
64*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
65*543adbedSBen Gras 	assert(e2 == NULL);
66*543adbedSBen Gras 	assertEqualString("test2", archive_entry_pathname(entry));
67*543adbedSBen Gras 	assertEqualString("test2", archive_entry_hardlink(entry));
68*543adbedSBen Gras 	assertEqualInt(0, archive_entry_size(entry));
69*543adbedSBen Gras 
70*543adbedSBen Gras 
71*543adbedSBen Gras 	/* Dirs should never be matched as hardlinks, regardless. */
72*543adbedSBen Gras 	archive_entry_set_pathname(entry, "test3");
73*543adbedSBen Gras 	archive_entry_set_nlink(entry, 2);
74*543adbedSBen Gras 	archive_entry_set_filetype(entry, AE_IFDIR);
75*543adbedSBen Gras 	archive_entry_set_ino(entry, 3);
76*543adbedSBen Gras 	archive_entry_set_hardlink(entry, NULL);
77*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
78*543adbedSBen Gras 	/* Shouldn't be altered, since it wasn't seen before. */
79*543adbedSBen Gras 	assert(e2 == NULL);
80*543adbedSBen Gras 	assertEqualString("test3", archive_entry_pathname(entry));
81*543adbedSBen Gras 	assertEqualString(NULL, archive_entry_hardlink(entry));
82*543adbedSBen Gras 
83*543adbedSBen Gras 	/* Dir, so it shouldn't get matched. */
84*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
85*543adbedSBen Gras 	assert(e2 == NULL);
86*543adbedSBen Gras 	assertEqualString("test3", archive_entry_pathname(entry));
87*543adbedSBen Gras 	assertEqualString(NULL, archive_entry_hardlink(entry));
88*543adbedSBen Gras 
89*543adbedSBen Gras 	archive_entry_free(entry);
90*543adbedSBen Gras 	archive_entry_linkresolver_free(resolver);
91*543adbedSBen Gras }
92*543adbedSBen Gras 
test_linkify_old_cpio(void)93*543adbedSBen Gras static void test_linkify_old_cpio(void)
94*543adbedSBen Gras {
95*543adbedSBen Gras 	struct archive_entry *entry, *e2;
96*543adbedSBen Gras 	struct archive_entry_linkresolver *resolver;
97*543adbedSBen Gras 
98*543adbedSBen Gras 	/* Initialize the resolver. */
99*543adbedSBen Gras 	assert(NULL != (resolver = archive_entry_linkresolver_new()));
100*543adbedSBen Gras 	archive_entry_linkresolver_set_strategy(resolver,
101*543adbedSBen Gras 	    ARCHIVE_FORMAT_CPIO_POSIX);
102*543adbedSBen Gras 
103*543adbedSBen Gras 	/* Create an entry with 2 link and try to linkify it. */
104*543adbedSBen Gras 	assert(NULL != (entry = archive_entry_new()));
105*543adbedSBen Gras 	archive_entry_set_pathname(entry, "test1");
106*543adbedSBen Gras 	archive_entry_set_ino(entry, 1);
107*543adbedSBen Gras 	archive_entry_set_dev(entry, 2);
108*543adbedSBen Gras 	archive_entry_set_nlink(entry, 2);
109*543adbedSBen Gras 	archive_entry_set_size(entry, 10);
110*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
111*543adbedSBen Gras 
112*543adbedSBen Gras 	/* Shouldn't have been changed. */
113*543adbedSBen Gras 	assert(e2 == NULL);
114*543adbedSBen Gras 	assertEqualInt(10, archive_entry_size(entry));
115*543adbedSBen Gras 	assertEqualString("test1", archive_entry_pathname(entry));
116*543adbedSBen Gras 
117*543adbedSBen Gras 	/* Still shouldn't be matched. */
118*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
119*543adbedSBen Gras 	assert(e2 == NULL);
120*543adbedSBen Gras 	assertEqualString("test1", archive_entry_pathname(entry));
121*543adbedSBen Gras 	assertEqualString(NULL, archive_entry_hardlink(entry));
122*543adbedSBen Gras 	assertEqualInt(10, archive_entry_size(entry));
123*543adbedSBen Gras 
124*543adbedSBen Gras 	archive_entry_free(entry);
125*543adbedSBen Gras 	archive_entry_linkresolver_free(resolver);
126*543adbedSBen Gras }
127*543adbedSBen Gras 
test_linkify_new_cpio(void)128*543adbedSBen Gras static void test_linkify_new_cpio(void)
129*543adbedSBen Gras {
130*543adbedSBen Gras 	struct archive_entry *entry, *e2;
131*543adbedSBen Gras 	struct archive_entry_linkresolver *resolver;
132*543adbedSBen Gras 
133*543adbedSBen Gras 	/* Initialize the resolver. */
134*543adbedSBen Gras 	assert(NULL != (resolver = archive_entry_linkresolver_new()));
135*543adbedSBen Gras 	archive_entry_linkresolver_set_strategy(resolver,
136*543adbedSBen Gras 	    ARCHIVE_FORMAT_CPIO_SVR4_NOCRC);
137*543adbedSBen Gras 
138*543adbedSBen Gras 	/* Create an entry with only 1 link and try to linkify it. */
139*543adbedSBen Gras 	assert(NULL != (entry = archive_entry_new()));
140*543adbedSBen Gras 	archive_entry_set_pathname(entry, "test1");
141*543adbedSBen Gras 	archive_entry_set_ino(entry, 1);
142*543adbedSBen Gras 	archive_entry_set_dev(entry, 2);
143*543adbedSBen Gras 	archive_entry_set_nlink(entry, 1);
144*543adbedSBen Gras 	archive_entry_set_size(entry, 10);
145*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
146*543adbedSBen Gras 
147*543adbedSBen Gras 	/* Shouldn't have been changed. */
148*543adbedSBen Gras 	assert(e2 == NULL);
149*543adbedSBen Gras 	assertEqualInt(10, archive_entry_size(entry));
150*543adbedSBen Gras 	assertEqualString("test1", archive_entry_pathname(entry));
151*543adbedSBen Gras 
152*543adbedSBen Gras 	/* Now, try again with an entry that has 3 links. */
153*543adbedSBen Gras 	archive_entry_set_pathname(entry, "test2");
154*543adbedSBen Gras 	archive_entry_set_nlink(entry, 3);
155*543adbedSBen Gras 	archive_entry_set_ino(entry, 2);
156*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
157*543adbedSBen Gras 
158*543adbedSBen Gras 	/* First time, it just gets swallowed. */
159*543adbedSBen Gras 	assert(entry == NULL);
160*543adbedSBen Gras 	assert(e2 == NULL);
161*543adbedSBen Gras 
162*543adbedSBen Gras 	/* Match again. */
163*543adbedSBen Gras 	assert(NULL != (entry = archive_entry_new()));
164*543adbedSBen Gras 	archive_entry_set_pathname(entry, "test3");
165*543adbedSBen Gras 	archive_entry_set_ino(entry, 2);
166*543adbedSBen Gras 	archive_entry_set_dev(entry, 2);
167*543adbedSBen Gras 	archive_entry_set_nlink(entry, 2);
168*543adbedSBen Gras 	archive_entry_set_size(entry, 10);
169*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
170*543adbedSBen Gras 
171*543adbedSBen Gras 	/* Should get back "test2" and nothing else. */
172*543adbedSBen Gras 	assertEqualString("test2", archive_entry_pathname(entry));
173*543adbedSBen Gras 	assertEqualInt(0, archive_entry_size(entry));
174*543adbedSBen Gras 	archive_entry_free(entry);
175*543adbedSBen Gras 	assert(NULL == e2);
176*543adbedSBen Gras 	archive_entry_free(e2); /* This should be a no-op. */
177*543adbedSBen Gras 
178*543adbedSBen Gras 	/* Match a third time. */
179*543adbedSBen Gras 	assert(NULL != (entry = archive_entry_new()));
180*543adbedSBen Gras 	archive_entry_set_pathname(entry, "test4");
181*543adbedSBen Gras 	archive_entry_set_ino(entry, 2);
182*543adbedSBen Gras 	archive_entry_set_dev(entry, 2);
183*543adbedSBen Gras 	archive_entry_set_nlink(entry, 3);
184*543adbedSBen Gras 	archive_entry_set_size(entry, 10);
185*543adbedSBen Gras 	archive_entry_linkify(resolver, &entry, &e2);
186*543adbedSBen Gras 
187*543adbedSBen Gras 	/* Should get back "test3". */
188*543adbedSBen Gras 	assertEqualString("test3", archive_entry_pathname(entry));
189*543adbedSBen Gras 	assertEqualInt(0, archive_entry_size(entry));
190*543adbedSBen Gras 
191*543adbedSBen Gras 	/* Since "test4" was the last link, should get it back also. */
192*543adbedSBen Gras 	assertEqualString("test4", archive_entry_pathname(e2));
193*543adbedSBen Gras 	assertEqualInt(10, archive_entry_size(e2));
194*543adbedSBen Gras 
195*543adbedSBen Gras 	archive_entry_free(entry);
196*543adbedSBen Gras 	archive_entry_free(e2);
197*543adbedSBen Gras 	archive_entry_linkresolver_free(resolver);
198*543adbedSBen Gras }
199*543adbedSBen Gras 
DEFINE_TEST(test_link_resolver)200*543adbedSBen Gras DEFINE_TEST(test_link_resolver)
201*543adbedSBen Gras {
202*543adbedSBen Gras 	test_linkify_tar();
203*543adbedSBen Gras 	test_linkify_old_cpio();
204*543adbedSBen Gras 	test_linkify_new_cpio();
205*543adbedSBen Gras }
206