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
test_linkify_tar(void)27 static void test_linkify_tar(void)
28 {
29 struct archive_entry *entry, *e2;
30 struct archive_entry_linkresolver *resolver;
31
32 /* Initialize the resolver. */
33 assert(NULL != (resolver = archive_entry_linkresolver_new()));
34 archive_entry_linkresolver_set_strategy(resolver,
35 ARCHIVE_FORMAT_TAR_USTAR);
36
37 /* Create an entry with only 1 link and try to linkify it. */
38 assert(NULL != (entry = archive_entry_new()));
39 archive_entry_set_pathname(entry, "test1");
40 archive_entry_set_ino(entry, 1);
41 archive_entry_set_dev(entry, 2);
42 archive_entry_set_nlink(entry, 1);
43 archive_entry_set_size(entry, 10);
44 archive_entry_linkify(resolver, &entry, &e2);
45
46 /* Shouldn't have been changed. */
47 assert(e2 == NULL);
48 assertEqualInt(10, archive_entry_size(entry));
49 assertEqualString("test1", archive_entry_pathname(entry));
50
51 /* Now, try again with an entry that has 2 links. */
52 archive_entry_set_pathname(entry, "test2");
53 archive_entry_set_nlink(entry, 2);
54 archive_entry_set_ino(entry, 2);
55 archive_entry_linkify(resolver, &entry, &e2);
56 /* Shouldn't be altered, since it wasn't seen before. */
57 assert(e2 == NULL);
58 assertEqualString("test2", archive_entry_pathname(entry));
59 assertEqualString(NULL, archive_entry_hardlink(entry));
60 assertEqualInt(10, archive_entry_size(entry));
61
62 /* Match again and make sure it does get altered. */
63 archive_entry_linkify(resolver, &entry, &e2);
64 assert(e2 == NULL);
65 assertEqualString("test2", archive_entry_pathname(entry));
66 assertEqualString("test2", archive_entry_hardlink(entry));
67 assertEqualInt(0, archive_entry_size(entry));
68
69
70 /* Dirs should never be matched as hardlinks, regardless. */
71 archive_entry_set_pathname(entry, "test3");
72 archive_entry_set_nlink(entry, 2);
73 archive_entry_set_filetype(entry, AE_IFDIR);
74 archive_entry_set_ino(entry, 3);
75 archive_entry_set_hardlink(entry, NULL);
76 archive_entry_linkify(resolver, &entry, &e2);
77 /* Shouldn't be altered, since it wasn't seen before. */
78 assert(e2 == NULL);
79 assertEqualString("test3", archive_entry_pathname(entry));
80 assertEqualString(NULL, archive_entry_hardlink(entry));
81
82 /* Dir, so it shouldn't get matched. */
83 archive_entry_linkify(resolver, &entry, &e2);
84 assert(e2 == NULL);
85 assertEqualString("test3", archive_entry_pathname(entry));
86 assertEqualString(NULL, archive_entry_hardlink(entry));
87
88 archive_entry_free(entry);
89 archive_entry_linkresolver_free(resolver);
90 }
91
test_linkify_old_cpio(void)92 static void test_linkify_old_cpio(void)
93 {
94 struct archive_entry *entry, *e2;
95 struct archive_entry_linkresolver *resolver;
96
97 /* Initialize the resolver. */
98 assert(NULL != (resolver = archive_entry_linkresolver_new()));
99 archive_entry_linkresolver_set_strategy(resolver,
100 ARCHIVE_FORMAT_CPIO_POSIX);
101
102 /* Create an entry with 2 link and try to linkify it. */
103 assert(NULL != (entry = archive_entry_new()));
104 archive_entry_set_pathname(entry, "test1");
105 archive_entry_set_ino(entry, 1);
106 archive_entry_set_dev(entry, 2);
107 archive_entry_set_nlink(entry, 2);
108 archive_entry_set_size(entry, 10);
109 archive_entry_linkify(resolver, &entry, &e2);
110
111 /* Shouldn't have been changed. */
112 assert(e2 == NULL);
113 assertEqualInt(10, archive_entry_size(entry));
114 assertEqualString("test1", archive_entry_pathname(entry));
115
116 /* Still shouldn't be matched. */
117 archive_entry_linkify(resolver, &entry, &e2);
118 assert(e2 == NULL);
119 assertEqualString("test1", archive_entry_pathname(entry));
120 assertEqualString(NULL, archive_entry_hardlink(entry));
121 assertEqualInt(10, archive_entry_size(entry));
122
123 archive_entry_free(entry);
124 archive_entry_linkresolver_free(resolver);
125 }
126
test_linkify_new_cpio(void)127 static void test_linkify_new_cpio(void)
128 {
129 struct archive_entry *entry, *e2;
130 struct archive_entry_linkresolver *resolver;
131
132 /* Initialize the resolver. */
133 assert(NULL != (resolver = archive_entry_linkresolver_new()));
134 archive_entry_linkresolver_set_strategy(resolver,
135 ARCHIVE_FORMAT_CPIO_SVR4_NOCRC);
136
137 /* Create an entry with only 1 link and try to linkify it. */
138 assert(NULL != (entry = archive_entry_new()));
139 archive_entry_set_pathname(entry, "test1");
140 archive_entry_set_ino(entry, 1);
141 archive_entry_set_dev(entry, 2);
142 archive_entry_set_nlink(entry, 1);
143 archive_entry_set_size(entry, 10);
144 archive_entry_linkify(resolver, &entry, &e2);
145
146 /* Shouldn't have been changed. */
147 assert(e2 == NULL);
148 assertEqualInt(10, archive_entry_size(entry));
149 assertEqualString("test1", archive_entry_pathname(entry));
150
151 /* Now, try again with an entry that has 3 links. */
152 archive_entry_set_pathname(entry, "test2");
153 archive_entry_set_nlink(entry, 3);
154 archive_entry_set_ino(entry, 2);
155 archive_entry_linkify(resolver, &entry, &e2);
156
157 /* First time, it just gets swallowed. */
158 assert(entry == NULL);
159 assert(e2 == NULL);
160
161 /* Match again. */
162 assert(NULL != (entry = archive_entry_new()));
163 archive_entry_set_pathname(entry, "test3");
164 archive_entry_set_ino(entry, 2);
165 archive_entry_set_dev(entry, 2);
166 archive_entry_set_nlink(entry, 2);
167 archive_entry_set_size(entry, 10);
168 archive_entry_linkify(resolver, &entry, &e2);
169
170 /* Should get back "test2" and nothing else. */
171 assertEqualString("test2", archive_entry_pathname(entry));
172 assertEqualInt(0, archive_entry_size(entry));
173 archive_entry_free(entry);
174 assert(NULL == e2);
175 archive_entry_free(e2); /* This should be a no-op. */
176
177 /* Match a third time. */
178 assert(NULL != (entry = archive_entry_new()));
179 archive_entry_set_pathname(entry, "test4");
180 archive_entry_set_ino(entry, 2);
181 archive_entry_set_dev(entry, 2);
182 archive_entry_set_nlink(entry, 3);
183 archive_entry_set_size(entry, 10);
184 archive_entry_linkify(resolver, &entry, &e2);
185
186 /* Should get back "test3". */
187 assertEqualString("test3", archive_entry_pathname(entry));
188 assertEqualInt(0, archive_entry_size(entry));
189
190 /* Since "test4" was the last link, should get it back also. */
191 assertEqualString("test4", archive_entry_pathname(e2));
192 assertEqualInt(10, archive_entry_size(e2));
193
194 archive_entry_free(entry);
195 archive_entry_free(e2);
196 archive_entry_linkresolver_free(resolver);
197 }
198
DEFINE_TEST(test_link_resolver)199 DEFINE_TEST(test_link_resolver)
200 {
201 test_linkify_tar();
202 test_linkify_old_cpio();
203 test_linkify_new_cpio();
204 }
205