Branch data Line data Source code
1 : : /*
2 : : * libdpkg - Debian packaging suite library routines
3 : : * tarfn.c - tar archive extraction functions
4 : : *
5 : : * Copyright © 1995 Bruce Perens
6 : : * Copyright © 2007-2011, 2013-2017 Guillem Jover <guillem@debian.org>
7 : : *
8 : : * This is free software; you can redistribute it and/or modify
9 : : * it under the terms of the GNU General Public License as published by
10 : : * the Free Software Foundation; either version 2 of the License, or
11 : : * (at your option) any later version.
12 : : *
13 : : * This is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : * GNU General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU General Public License
19 : : * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #include <config.h>
23 : : #include <compat.h>
24 : :
25 : : #ifdef HAVE_SYS_SYSMACROS_H
26 : : #include <sys/sysmacros.h>
27 : : #endif
28 : : #include <sys/stat.h>
29 : :
30 : : #include <errno.h>
31 : : #include <string.h>
32 : : #include <pwd.h>
33 : : #include <grp.h>
34 : : #include <unistd.h>
35 : : #include <inttypes.h>
36 : : #include <stdlib.h>
37 : : #include <stdio.h>
38 : :
39 : : #include <dpkg/macros.h>
40 : : #include <dpkg/dpkg.h>
41 : : #include <dpkg/i18n.h>
42 : : #include <dpkg/error.h>
43 : : #include <dpkg/tarfn.h>
44 : :
45 : : #define TAR_MAGIC_USTAR "ustar\0" "00"
46 : : #define TAR_MAGIC_GNU "ustar " " \0"
47 : :
48 : : #define TAR_TYPE_SIGNED(t) (!((t)0 < (t)-1))
49 : :
50 : : #define TAR_TYPE_MIN(t) \
51 : : (TAR_TYPE_SIGNED(t) ? \
52 : : ~(t)TAR_TYPE_MAX(t) : \
53 : : (t)0)
54 : : #define TAR_TYPE_MAX(t) \
55 : : (TAR_TYPE_SIGNED(t) ? \
56 : : ((((t)1 << (sizeof(t) * 8 - 2)) - 1) * 2 + 1) : \
57 : : ~(t)0)
58 : :
59 : : #define TAR_ATOUL(str, type) \
60 : : (type)tar_atoul(str, sizeof(str), TAR_TYPE_MAX(type))
61 : : #define TAR_ATOSL(str, type) \
62 : : (type)tar_atosl(str, sizeof(str), TAR_TYPE_MIN(type), TAR_TYPE_MAX(type))
63 : :
64 : : struct tar_header {
65 : : char name[100] DPKG_ATTR_NONSTRING;
66 : : char mode[8] DPKG_ATTR_NONSTRING;
67 : : char uid[8] DPKG_ATTR_NONSTRING;
68 : : char gid[8] DPKG_ATTR_NONSTRING;
69 : : char size[12] DPKG_ATTR_NONSTRING;
70 : : char mtime[12] DPKG_ATTR_NONSTRING;
71 : : char checksum[8] DPKG_ATTR_NONSTRING;
72 : : char linkflag;
73 : : char linkname[100] DPKG_ATTR_NONSTRING;
74 : :
75 : : /* Only valid on ustar and gnu. */
76 : : char magic[8] DPKG_ATTR_NONSTRING;
77 : : char user[32] DPKG_ATTR_NONSTRING;
78 : : char group[32] DPKG_ATTR_NONSTRING;
79 : : char devmajor[8] DPKG_ATTR_NONSTRING;
80 : : char devminor[8] DPKG_ATTR_NONSTRING;
81 : :
82 : : /* Only valid on ustar. */
83 : : char prefix[155] DPKG_ATTR_NONSTRING;
84 : : };
85 : :
86 : : static inline uintmax_t
87 : 455 : tar_ret_errno(int err, uintmax_t ret)
88 : : {
89 : 455 : errno = err;
90 : 455 : return ret;
91 : : }
92 : :
93 : : /**
94 : : * Convert an ASCII octal string to an intmax_t.
95 : : */
96 : : static uintmax_t
97 : 443 : tar_atol8(const char *s, size_t size)
98 : : {
99 : 443 : const char *end = s + size;
100 : 443 : uintmax_t n = 0;
101 : :
102 : : /* Old implementations might precede the value with spaces. */
103 [ + + + + ]: 509 : while (s < end && *s == ' ')
104 : 66 : s++;
105 : :
106 [ + + ]: 443 : if (s == end)
107 : 1 : return tar_ret_errno(EINVAL, 0);
108 : :
109 [ + + ]: 3834 : while (s < end) {
110 [ + + + - ]: 3830 : if (*s == '\0' || *s == ' ')
111 : : break;
112 [ + - + + ]: 3396 : if (*s < '0' || *s > '7')
113 : 4 : return tar_ret_errno(ERANGE, 0);
114 : 3392 : n = (n * 010) + (*s++ - '0');
115 : : }
116 : :
117 [ + + ]: 1144 : while (s < end) {
118 [ + + - + ]: 706 : if (*s != '\0' && *s != ' ')
119 : 0 : return tar_ret_errno(EINVAL, 0);
120 : 706 : s++;
121 : : }
122 : :
123 : 438 : return tar_ret_errno(0, n);
124 : : }
125 : :
126 : : /**
127 : : * Convert a base-256 two-complement number to an intmax_t.
128 : : */
129 : : static uintmax_t
130 : 12 : tar_atol256(const char *s, size_t size, intmax_t min, uintmax_t max)
131 : : {
132 : 12 : uintmax_t n = 0;
133 : : unsigned char c;
134 : : int sign;
135 : :
136 : : /* The encoding always sets the first bit to one, so that it can be
137 : : * distinguished from the ASCII encoding. For positive numbers we
138 : : * need to reset it. For negative numbers we initialize n to -1. */
139 : 12 : c = *s++;
140 [ + + ]: 12 : if (c == 0x80)
141 : 6 : c = 0;
142 : : else
143 : 6 : n = ~(uintmax_t)0;
144 : 12 : sign = c;
145 : :
146 : : /* Check for overflows. */
147 [ + + ]: 55 : while (size > sizeof(uintmax_t)) {
148 [ + + ]: 45 : if (c != sign)
149 [ + + ]: 2 : return tar_ret_errno(ERANGE, sign ? (uintmax_t)min : max);
150 : 43 : c = *s++;
151 : 43 : size--;
152 : : }
153 : :
154 [ + + ]: 10 : if ((c & 0x80) != (sign & 0x80))
155 [ + + ]: 2 : return tar_ret_errno(ERANGE, sign ? (uintmax_t)min : max);
156 : :
157 : : for (;;) {
158 : 64 : n = (n << 8) | c;
159 [ + + ]: 64 : if (--size == 0)
160 : 8 : break;
161 : 56 : c = *s++;
162 : : }
163 : :
164 : 8 : return tar_ret_errno(0, n);
165 : : }
166 : :
167 : : static uintmax_t
168 : 384 : tar_atol(const char *s, size_t size, intmax_t min, uintmax_t max)
169 : : {
170 : 384 : const unsigned char *a = (const unsigned char *)s;
171 : :
172 : : /* Check if it is a long two-complement base-256 number, positive or
173 : : * negative. */
174 [ + + + + ]: 384 : if (*a == 0xff || *a == 0x80)
175 : 12 : return tar_atol256(s, size, min, max);
176 : : else
177 : 372 : return tar_atol8(s, size);
178 : : }
179 : :
180 : : uintmax_t
181 : 307 : tar_atoul(const char *s, size_t size, uintmax_t max)
182 : : {
183 : 307 : uintmax_t n = tar_atol(s, size, 0, UINTMAX_MAX);
184 : :
185 [ - + ]: 307 : if (n > max)
186 : 0 : return tar_ret_errno(ERANGE, UINTMAX_MAX);
187 : :
188 : 307 : return n;
189 : : }
190 : :
191 : : intmax_t
192 : 77 : tar_atosl(const char *s, size_t size, intmax_t min, intmax_t max)
193 : : {
194 : 77 : intmax_t n = tar_atol(s, size, INTMAX_MIN, INTMAX_MAX);
195 : :
196 [ - + ]: 77 : if (n < min)
197 : 0 : return tar_ret_errno(ERANGE, INTMAX_MIN);
198 [ - + ]: 77 : if (n > max)
199 : 0 : return tar_ret_errno(ERANGE, INTMAX_MAX);
200 : :
201 : 77 : return n;
202 : : }
203 : :
204 : : static char *
205 : 4 : tar_header_get_prefix_name(struct tar_header *h)
206 : : {
207 : 4 : struct varbuf path = VARBUF_INIT;
208 : :
209 : 4 : varbuf_add_strn(&path, h->prefix, sizeof(h->prefix));
210 : 4 : varbuf_add_char(&path, '/');
211 : 4 : varbuf_add_strn(&path, h->name, sizeof(h->name));
212 : :
213 : 4 : return path.buf;
214 : : }
215 : :
216 : : static mode_t
217 : 71 : tar_header_get_unix_mode(struct tar_header *h)
218 : : {
219 : : mode_t mode;
220 : : enum tar_filetype type;
221 : :
222 : 71 : type = (enum tar_filetype)h->linkflag;
223 : :
224 [ + + + - : 71 : switch (type) {
- + + ]
225 : 15 : case TAR_FILETYPE_FILE0:
226 : : case TAR_FILETYPE_FILE:
227 : : case TAR_FILETYPE_HARDLINK:
228 : 15 : mode = S_IFREG;
229 : 15 : break;
230 : 14 : case TAR_FILETYPE_SYMLINK:
231 : 14 : mode = S_IFLNK;
232 : 14 : break;
233 : 29 : case TAR_FILETYPE_DIR:
234 : 29 : mode = S_IFDIR;
235 : 29 : break;
236 : 0 : case TAR_FILETYPE_CHARDEV:
237 : 0 : mode = S_IFCHR;
238 : 0 : break;
239 : 0 : case TAR_FILETYPE_BLOCKDEV:
240 : 0 : mode = S_IFBLK;
241 : 0 : break;
242 : 3 : case TAR_FILETYPE_FIFO:
243 : 3 : mode = S_IFIFO;
244 : 3 : break;
245 : 10 : default:
246 : 10 : mode = 0;
247 : 10 : break;
248 : : }
249 : :
250 : 71 : mode |= TAR_ATOUL(h->mode, mode_t) & 07777;
251 : :
252 : 71 : return mode;
253 : : }
254 : :
255 : : static long
256 : 71 : tar_header_checksum(struct tar_header *h)
257 : : {
258 : 71 : unsigned char *s = (unsigned char *)h;
259 : : unsigned int i;
260 : 71 : const size_t checksum_offset = offsetof(struct tar_header, checksum);
261 : : long sum;
262 : :
263 : : /* Treat checksum field as all blank. */
264 : 71 : sum = ' ' * sizeof(h->checksum);
265 : :
266 [ + + ]: 10579 : for (i = checksum_offset; i > 0; i--)
267 : 10508 : sum += *s++;
268 : :
269 : : /* Skip the real checksum field. */
270 : 71 : s += sizeof(h->checksum);
271 : :
272 [ + + ]: 25347 : for (i = TARBLKSZ - checksum_offset - sizeof(h->checksum); i > 0; i--)
273 : 25276 : sum += *s++;
274 : :
275 : 71 : return sum;
276 : : }
277 : :
278 : : static int
279 : 71 : tar_header_decode(struct tar_header *h, struct tar_entry *d, struct dpkg_error *err)
280 : : {
281 : : long checksum;
282 : :
283 : 71 : errno = 0;
284 : :
285 [ + + ]: 71 : if (memcmp(h->magic, TAR_MAGIC_GNU, 6) == 0)
286 : 42 : d->format = TAR_FORMAT_GNU;
287 [ + + ]: 29 : else if (memcmp(h->magic, TAR_MAGIC_USTAR, 6) == 0)
288 : 15 : d->format = TAR_FORMAT_USTAR;
289 : : else
290 : 14 : d->format = TAR_FORMAT_OLD;
291 : :
292 : 71 : d->type = (enum tar_filetype)h->linkflag;
293 [ + + ]: 71 : if (d->type == TAR_FILETYPE_FILE0)
294 : 5 : d->type = TAR_FILETYPE_FILE;
295 : :
296 : : /* Concatenate prefix and name to support ustar style long names. */
297 [ + + + + ]: 71 : if (d->format == TAR_FORMAT_USTAR && h->prefix[0] != '\0')
298 : 4 : d->name = tar_header_get_prefix_name(h);
299 : : else
300 : 67 : d->name = m_strndup(h->name, sizeof(h->name));
301 : 71 : d->linkname = m_strndup(h->linkname, sizeof(h->linkname));
302 : 71 : d->stat.mode = tar_header_get_unix_mode(h);
303 : : /* Even though off_t is signed, we use an unsigned parser here because
304 : : * negative offsets are not allowed. */
305 : 71 : d->size = TAR_ATOUL(h->size, off_t);
306 [ - + ]: 71 : if (errno)
307 : 0 : return dpkg_put_errno(err, _("invalid tar header size field"));
308 : 71 : d->mtime = TAR_ATOSL(h->mtime, time_t);
309 [ - + ]: 71 : if (errno)
310 : 0 : return dpkg_put_errno(err, _("invalid tar header mtime field"));
311 : :
312 [ + - - + ]: 71 : if (d->type == TAR_FILETYPE_CHARDEV || d->type == TAR_FILETYPE_BLOCKDEV)
313 : 0 : d->dev = makedev(TAR_ATOUL(h->devmajor, dev_t),
314 : : TAR_ATOUL(h->devminor, dev_t));
315 : : else
316 : 71 : d->dev = makedev(0, 0);
317 : :
318 [ + + ]: 71 : if (*h->user)
319 : 57 : d->stat.uname = m_strndup(h->user, sizeof(h->user));
320 : : else
321 : 14 : d->stat.uname = NULL;
322 : 71 : d->stat.uid = TAR_ATOUL(h->uid, uid_t);
323 [ - + ]: 71 : if (errno)
324 : 0 : return dpkg_put_errno(err, _("invalid tar header uid field"));
325 : :
326 [ + + ]: 71 : if (*h->group)
327 : 57 : d->stat.gname = m_strndup(h->group, sizeof(h->group));
328 : : else
329 : 14 : d->stat.gname = NULL;
330 : 71 : d->stat.gid = TAR_ATOUL(h->gid, gid_t);
331 [ - + ]: 71 : if (errno)
332 : 0 : return dpkg_put_errno(err, _("invalid tar header gid field"));
333 : :
334 : 71 : checksum = tar_atol8(h->checksum, sizeof(h->checksum));
335 [ - + ]: 71 : if (errno)
336 : 0 : return dpkg_put_errno(err, _("invalid tar header checksum field"));
337 : :
338 [ + + ]: 71 : if (tar_header_checksum(h) != checksum)
339 : 4 : return dpkg_put_error(err, _("invalid tar header checksum"));
340 : :
341 : 67 : return 0;
342 : : }
343 : :
344 : : /**
345 : : * Decode a GNU longlink or longname from the tar archive.
346 : : *
347 : : * The way the GNU long{link,name} stuff works is like this:
348 : : *
349 : : * - The first header is a “dummy” header that contains the size of the
350 : : * filename (GNU tar includes the terminating NUL character in the size,
351 : : * but other implementations do not).
352 : : * - The next N headers contain the filename (GNU tar terminates the string
353 : : * with a NUL character, but other implementations do not).
354 : : * - After the headers with the filename comes the “real” header with a
355 : : * bogus name or link.
356 : : *
357 : : * To be robust against any input, we need to always terminate the filename
358 : : * with a NUL character.
359 : : */
360 : : static int
361 : 10 : tar_gnu_long(struct tar_archive *tar, struct tar_entry *te, char **longp)
362 : : {
363 : : char buf[TARBLKSZ];
364 : : char *bp;
365 : 10 : int status = 0;
366 : : int long_read;
367 : :
368 : 10 : free(*longp);
369 : 10 : *longp = bp = m_malloc(te->size + 1);
370 : :
371 [ + + ]: 20 : for (long_read = te->size; long_read > 0; long_read -= TARBLKSZ) {
372 : : int copysize;
373 : :
374 : 10 : status = tar->ops->read(tar, buf, TARBLKSZ);
375 [ + - ]: 10 : if (status == TARBLKSZ)
376 : 10 : status = 0;
377 : : else {
378 : : /* Read partial header record? */
379 [ # # ]: 0 : if (status > 0) {
380 : 0 : errno = 0;
381 : 0 : status = dpkg_put_error(&tar->err,
382 : 0 : _("partially read tar header"));
383 : : }
384 : :
385 : : /* If we didn't get TARBLKSZ bytes read, punt. */
386 : 0 : break;
387 : : }
388 : :
389 : 10 : copysize = min(long_read, TARBLKSZ);
390 : 10 : memcpy(bp, buf, copysize);
391 : 10 : bp += copysize;
392 : : }
393 : 10 : *bp = '\0';
394 : :
395 : 10 : return status;
396 : : }
397 : :
398 : : static void
399 : 14 : tar_entry_copy(struct tar_entry *dst, struct tar_entry *src)
400 : : {
401 : 14 : memcpy(dst, src, sizeof(struct tar_entry));
402 : :
403 : 14 : dst->name = m_strdup(src->name);
404 : 14 : dst->linkname = m_strdup(src->linkname);
405 : :
406 [ + + ]: 14 : if (src->stat.uname)
407 : 11 : dst->stat.uname = m_strdup(src->stat.uname);
408 [ + + ]: 14 : if (src->stat.gname)
409 : 11 : dst->stat.gname = m_strdup(src->stat.gname);
410 : 14 : }
411 : :
412 : : static void
413 : 85 : tar_entry_destroy(struct tar_entry *te)
414 : : {
415 : 85 : free(te->name);
416 : 85 : free(te->linkname);
417 : 85 : free(te->stat.uname);
418 : 85 : free(te->stat.gname);
419 : :
420 : 85 : memset(te, 0, sizeof(*te));
421 : 85 : }
422 : :
423 : : struct tar_symlink_entry {
424 : : struct tar_symlink_entry *next;
425 : : struct tar_entry h;
426 : : };
427 : :
428 : : /**
429 : : * Update the tar entry from system information.
430 : : *
431 : : * Normalize UID and GID relative to the current system.
432 : : */
433 : : void
434 : 0 : tar_entry_update_from_system(struct tar_entry *te)
435 : : {
436 : : struct passwd *passwd;
437 : : struct group *group;
438 : :
439 [ # # ]: 0 : if (te->stat.uname) {
440 : 0 : passwd = getpwnam(te->stat.uname);
441 [ # # ]: 0 : if (passwd)
442 : 0 : te->stat.uid = passwd->pw_uid;
443 : : }
444 [ # # ]: 0 : if (te->stat.gname) {
445 : 0 : group = getgrnam(te->stat.gname);
446 [ # # ]: 0 : if (group)
447 : 0 : te->stat.gid = group->gr_gid;
448 : : }
449 : 0 : }
450 : :
451 : : int
452 : 4 : tar_extractor(struct tar_archive *tar)
453 : : {
454 : : int status;
455 : : char buffer[TARBLKSZ];
456 : : struct tar_entry h;
457 : :
458 : : char *next_long_name, *next_long_link;
459 : : struct tar_symlink_entry *symlink_head, *symlink_tail, *symlink_node;
460 : :
461 : 4 : next_long_name = NULL;
462 : 4 : next_long_link = NULL;
463 : 4 : symlink_tail = symlink_head = NULL;
464 : :
465 : 4 : h.name = NULL;
466 : 4 : h.linkname = NULL;
467 : 4 : h.stat.uname = NULL;
468 : 4 : h.stat.gname = NULL;
469 : :
470 [ + - ]: 71 : while ((status = tar->ops->read(tar, buffer, TARBLKSZ)) == TARBLKSZ) {
471 : : int name_len;
472 : :
473 [ + + ]: 71 : if (tar_header_decode((struct tar_header *)buffer, &h, &tar->err) < 0) {
474 [ + - ]: 4 : if (h.name[0] == '\0') {
475 : : /* The checksum failed on the terminating
476 : : * End Of Tape block entry of zeros. */
477 : 4 : dpkg_error_destroy(&tar->err);
478 : :
479 : : /* End Of Tape. */
480 : 4 : status = 0;
481 : : } else {
482 : 0 : status = -1;
483 : : }
484 : 4 : tar_entry_destroy(&h);
485 : 4 : break;
486 : : }
487 [ + + ]: 67 : if (h.type != TAR_FILETYPE_GNU_LONGLINK &&
488 [ + + ]: 65 : h.type != TAR_FILETYPE_GNU_LONGNAME) {
489 [ + + ]: 57 : if (next_long_name) {
490 : 8 : free(h.name);
491 : 8 : h.name = next_long_name;
492 : : }
493 : :
494 [ + + ]: 57 : if (next_long_link) {
495 : 2 : free(h.linkname);
496 : 2 : h.linkname = next_long_link;
497 : : }
498 : :
499 : 57 : next_long_link = NULL;
500 : 57 : next_long_name = NULL;
501 : : }
502 : :
503 [ - + ]: 67 : if (h.name[0] == '\0') {
504 : 0 : status = dpkg_put_error(&tar->err,
505 : 0 : _("invalid tar header with empty name field"));
506 : 0 : errno = 0;
507 : 0 : tar_entry_destroy(&h);
508 : 0 : break;
509 : : }
510 : :
511 : 67 : name_len = strlen(h.name);
512 : :
513 [ + + + + : 67 : switch (h.type) {
+ + + - -
- - ]
514 : 7 : case TAR_FILETYPE_FILE:
515 : : /* Compatibility with pre-ANSI ustar. */
516 [ + - ]: 7 : if (h.name[name_len - 1] != '/') {
517 : 7 : status = tar->ops->extract_file(tar, &h);
518 : 7 : break;
519 : : }
520 : : /* Else, fall through. */
521 : : case TAR_FILETYPE_DIR:
522 [ + - ]: 29 : if (h.name[name_len - 1] == '/') {
523 : 29 : h.name[name_len - 1] = '\0';
524 : : }
525 : 29 : status = tar->ops->mkdir(tar, &h);
526 : 29 : break;
527 : 4 : case TAR_FILETYPE_HARDLINK:
528 : 4 : status = tar->ops->link(tar, &h);
529 : 4 : break;
530 : 14 : case TAR_FILETYPE_SYMLINK:
531 : 14 : symlink_node = m_malloc(sizeof(*symlink_node));
532 : 14 : symlink_node->next = NULL;
533 : 14 : tar_entry_copy(&symlink_node->h, &h);
534 : :
535 [ + + ]: 14 : if (symlink_head)
536 : 10 : symlink_tail->next = symlink_node;
537 : : else
538 : 4 : symlink_head = symlink_node;
539 : 14 : symlink_tail = symlink_node;
540 : 14 : status = 0;
541 : 14 : break;
542 : 3 : case TAR_FILETYPE_CHARDEV:
543 : : case TAR_FILETYPE_BLOCKDEV:
544 : : case TAR_FILETYPE_FIFO:
545 : 3 : status = tar->ops->mknod(tar, &h);
546 : 3 : break;
547 : 2 : case TAR_FILETYPE_GNU_LONGLINK:
548 : 2 : status = tar_gnu_long(tar, &h, &next_long_link);
549 : 2 : break;
550 : 8 : case TAR_FILETYPE_GNU_LONGNAME:
551 : 8 : status = tar_gnu_long(tar, &h, &next_long_name);
552 : 8 : break;
553 : 0 : case TAR_FILETYPE_GNU_VOLUME:
554 : : case TAR_FILETYPE_GNU_MULTIVOL:
555 : : case TAR_FILETYPE_GNU_SPARSE:
556 : : case TAR_FILETYPE_GNU_DUMPDIR:
557 : 0 : status = dpkg_put_error(&tar->err,
558 : 0 : _("unsupported GNU tar header type '%c'"),
559 : 0 : h.type);
560 : 0 : errno = 0;
561 : 0 : break;
562 : 0 : case TAR_FILETYPE_SOLARIS_EXTENDED:
563 : : case TAR_FILETYPE_SOLARIS_ACL:
564 : 0 : status = dpkg_put_error(&tar->err,
565 : 0 : _("unsupported Solaris tar header type '%c'"),
566 : 0 : h.type);
567 : 0 : errno = 0;
568 : 0 : break;
569 : 0 : case TAR_FILETYPE_PAX_GLOBAL:
570 : : case TAR_FILETYPE_PAX_EXTENDED:
571 : 0 : status = dpkg_put_error(&tar->err,
572 : 0 : _("unsupported PAX tar header type '%c'"),
573 : 0 : h.type);
574 : 0 : errno = 0;
575 : 0 : break;
576 : 0 : default:
577 : 0 : status = dpkg_put_error(&tar->err,
578 : 0 : _("unknown tar header type '%c'"),
579 : 0 : h.type);
580 : 0 : errno = 0;
581 : : }
582 : 67 : tar_entry_destroy(&h);
583 [ - + ]: 67 : if (status != 0)
584 : : /* Pass on status from coroutine. */
585 : 0 : break;
586 : : }
587 : :
588 [ + + ]: 18 : while (symlink_head) {
589 : 14 : symlink_node = symlink_head->next;
590 [ + - ]: 14 : if (status == 0)
591 : 14 : status = tar->ops->symlink(tar, &symlink_head->h);
592 : 14 : tar_entry_destroy(&symlink_head->h);
593 : 14 : free(symlink_head);
594 : 14 : symlink_head = symlink_node;
595 : : }
596 : : /* Make sure we free the long names, in case of a bogus or truncated
597 : : * tar archive with long entries not followed by a normal entry. */
598 : 4 : free(next_long_name);
599 : 4 : free(next_long_link);
600 : :
601 [ - + ]: 4 : if (status > 0) {
602 : 0 : status = dpkg_put_error(&tar->err,
603 : 0 : _("partially read tar header"));
604 : 0 : errno = 0;
605 : : }
606 : :
607 : : /* Return whatever I/O function returned. */
608 : 4 : return status;
609 : : }
|