This source file includes following definitions.
- decode_num
- sparse_select_optab
- sparse_init
- sparse_done
- sparse_member_p
- sparse_fixup_header
- sparse_decode_header
- sparse_add_map
- oldgnu_add_sparse
- oldgnu_sparse_member_p
- oldgnu_fixup_header
- oldgnu_get_sparse_info
- star_sparse_member_p
- star_fixup_header
- star_get_sparse_info
- pax_sparse_member_p
- pax_decode_header
- tar_sparse_member_p
- tar_sparse_fixup_header
- tar_sparse_skip_file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #if defined(__GNUC__) && (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4))
39 #pragma GCC diagnostic ignored "-Wtype-limits"
40 #endif
41
42 #include <config.h>
43
44 #include <ctype.h>
45 #include <errno.h>
46 #include <inttypes.h>
47
48 #include "lib/global.h"
49
50 #include "tar-internal.h"
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)
76
77
78
79
80 #define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)
81
82
83
84 #if (2 <= __GNUC__ \
85 || (4 <= __clang_major__) \
86 || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \
87 || (0x5110 <= __SUNPRO_C && !__STDC__))
88 #define _GL_HAVE___TYPEOF__ 1
89 #else
90 #define _GL_HAVE___TYPEOF__ 0
91 #endif
92
93
94
95
96
97 #if _GL_HAVE___TYPEOF__
98 #define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t))
99 #else
100 #define _GL_SIGNED_TYPE_OR_EXPR(t) 1
101 #endif
102
103
104
105 #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))
106
107
108
109 #define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))
110
111
112
113 #define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
114
115 #define _GL_SIGNED_INT_MAXIMUM(e) \
116 (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)
117
118
119
120 #define _GL_INT_MINIMUM(e) \
121 (EXPR_SIGNED (e) \
122 ? ~_GL_SIGNED_INT_MAXIMUM (e) \
123 : _GL_INT_CONVERT (e, 0))
124 #define _GL_INT_MAXIMUM(e) \
125 (EXPR_SIGNED (e) \
126 ? _GL_SIGNED_INT_MAXIMUM (e) \
127 : _GL_INT_NEGATE_CONVERT (e, 1))
128
129
130
131
132
133 #define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \
134 op_result_overflow (a, b, \
135 _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \
136 _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b)))
137
138 #define INT_ADD_RANGE_OVERFLOW(a, b, min, max) \
139 ((b) < 0 \
140 ? (a) < (min) - (b) \
141 : (max) - (b) < (a))
142
143
144
145
146 #if defined __clang__ || defined __ICC
147
148
149
150
151 #define _GL_HAS_BUILTIN_OVERFLOW_P 0
152 #elif defined __has_builtin
153 #define _GL_HAS_BUILTIN_OVERFLOW_P __has_builtin (__builtin_mul_overflow_p)
154 #else
155 #define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__)
156 #endif
157
158
159
160
161
162 #if _GL_HAS_BUILTIN_OVERFLOW_P
163 #define _GL_ADD_OVERFLOW(a, b, min, max) \
164 __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0)
165 #else
166 #define _GL_ADD_OVERFLOW(a, b, min, max) \
167 ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \
168 : (a) < 0 ? (b) <= (a) + (b) \
169 : (b) < 0 ? (a) <= (a) + (b) \
170 : (a) + (b) < (b))
171 #endif
172
173
174
175
176
177
178
179
180
181
182 #define INT_STRLEN_BOUND(t) \
183 (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - _GL_SIGNED_TYPE_OR_EXPR (t)) \
184 + _GL_SIGNED_TYPE_OR_EXPR (t))
185
186
187
188 #define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
189
190 #define UINTMAX_STRSIZE_BOUND INT_BUFSIZE_BOUND (uintmax_t)
191
192 #define INT_ADD_OVERFLOW(a, b) \
193 _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW)
194
195 #define SPARSES_INIT_COUNT SPARSES_IN_SPARSE_HEADER
196
197 #define COPY_BUF(arch,b,buf,src) \
198 do \
199 { \
200 char *endp = b->buffer + BLOCKSIZE; \
201 char *dst = buf; \
202 do \
203 { \
204 if (dst == buf + UINTMAX_STRSIZE_BOUND - 1) \
205 \
206 return FALSE; \
207 if (src == endp) \
208 { \
209 tar_set_next_block_after (b); \
210 b = tar_find_next_block (arch); \
211 if (b == NULL) \
212 \
213 return FALSE; \
214 src = b->buffer; \
215 endp = b->buffer + BLOCKSIZE; \
216 } \
217 *dst = *src++; \
218 } \
219 while (*dst++ != '\n'); \
220 dst[-1] = '\0'; \
221 } \
222 while (FALSE)
223
224
225
226 struct tar_sparse_file;
227
228 struct tar_sparse_optab
229 {
230 gboolean (*init) (struct tar_sparse_file * file);
231 gboolean (*done) (struct tar_sparse_file * file);
232 gboolean (*sparse_member_p) (struct tar_sparse_file * file);
233 gboolean (*fixup_header) (struct tar_sparse_file * file);
234 gboolean (*decode_header) (tar_super_t * archive, struct tar_sparse_file * file);
235 };
236
237 struct tar_sparse_file
238 {
239 int fd;
240 off_t dumped_size;
241 struct tar_stat_info *stat_info;
242 struct tar_sparse_optab const *optab;
243 void *closure;
244 };
245
246 enum oldgnu_add_status
247 {
248 add_ok,
249 add_finish,
250 add_fail
251 };
252
253
254
255 static gboolean oldgnu_sparse_member_p (struct tar_sparse_file *file);
256 static gboolean oldgnu_fixup_header (struct tar_sparse_file *file);
257 static gboolean oldgnu_get_sparse_info (tar_super_t * archive, struct tar_sparse_file *file);
258
259 static gboolean star_sparse_member_p (struct tar_sparse_file *file);
260 static gboolean star_fixup_header (struct tar_sparse_file *file);
261 static gboolean star_get_sparse_info (tar_super_t * archive, struct tar_sparse_file *file);
262
263 static gboolean pax_sparse_member_p (struct tar_sparse_file *file);
264 static gboolean pax_decode_header (tar_super_t * archive, struct tar_sparse_file *file);
265
266
267
268
269 static struct tar_sparse_optab const oldgnu_optab =
270 {
271 .init = NULL,
272 .done = NULL,
273 .sparse_member_p = oldgnu_sparse_member_p,
274 .fixup_header = oldgnu_fixup_header,
275 .decode_header = oldgnu_get_sparse_info
276 };
277
278
279
280 static struct tar_sparse_optab const star_optab =
281 {
282 .init = NULL,
283 .done = NULL,
284 .sparse_member_p = star_sparse_member_p,
285 .fixup_header = star_fixup_header,
286 .decode_header = star_get_sparse_info
287 };
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355 static struct tar_sparse_optab const pax_optab = {
356 .init = NULL,
357 .done = NULL,
358 .sparse_member_p = pax_sparse_member_p,
359 .fixup_header = NULL,
360 .decode_header = pax_decode_header
361 };
362
363
364
365
366
367 static gboolean
368 decode_num (uintmax_t * num, const char *arg, uintmax_t maxval)
369 {
370 uintmax_t u;
371 char *arg_lim;
372
373 if (!isdigit (*arg))
374 return FALSE;
375
376 errno = 0;
377 u = (uintmax_t) g_ascii_strtoll (arg, &arg_lim, 10);
378
379 if (!(u <= maxval && errno != ERANGE) || *arg_lim != '\0')
380 return FALSE;
381
382 *num = u;
383 return TRUE;
384 }
385
386
387
388 static gboolean
389 sparse_select_optab (const tar_super_t * archive, struct tar_sparse_file *file)
390 {
391 switch (archive->type)
392 {
393 case TAR_V7:
394 case TAR_USTAR:
395 return FALSE;
396
397 case TAR_OLDGNU:
398 case TAR_GNU:
399 file->optab = &oldgnu_optab;
400 break;
401
402 case TAR_POSIX:
403 file->optab = &pax_optab;
404 break;
405
406 case TAR_STAR:
407 file->optab = &star_optab;
408 break;
409
410 default:
411 return FALSE;
412 }
413
414 return TRUE;
415 }
416
417
418
419 static gboolean
420 sparse_init (tar_super_t * archive, struct tar_sparse_file *file)
421 {
422 memset (file, 0, sizeof (*file));
423
424 if (!sparse_select_optab (archive, file))
425 return FALSE;
426
427 if (file->optab->init != NULL)
428 return file->optab->init (file);
429
430 return TRUE;
431 }
432
433
434
435 static gboolean
436 sparse_done (struct tar_sparse_file *file)
437 {
438 if (file->optab->done != NULL)
439 return file->optab->done (file);
440
441 return TRUE;
442 }
443
444
445
446 static gboolean
447 sparse_member_p (struct tar_sparse_file *file)
448 {
449 if (file->optab->sparse_member_p != NULL)
450 return file->optab->sparse_member_p (file);
451
452 return FALSE;
453 }
454
455
456
457 static gboolean
458 sparse_fixup_header (struct tar_sparse_file *file)
459 {
460 if (file->optab->fixup_header != NULL)
461 return file->optab->fixup_header (file);
462
463 return TRUE;
464 }
465
466
467
468 static gboolean
469 sparse_decode_header (tar_super_t * archive, struct tar_sparse_file *file)
470 {
471 if (file->optab->decode_header != NULL)
472 return file->optab->decode_header (archive, file);
473
474 return TRUE;
475 }
476
477
478
479 static inline void
480 sparse_add_map (struct tar_stat_info *st, struct sp_array *sp)
481 {
482 if (st->sparse_map == NULL)
483 st->sparse_map = g_array_sized_new (FALSE, FALSE, sizeof (struct sp_array), 1);
484 g_array_append_val (st->sparse_map, *sp);
485 }
486
487
488
489
490
491
492 static enum oldgnu_add_status
493 oldgnu_add_sparse (struct tar_sparse_file *file, struct sparse *s)
494 {
495 struct sp_array sp;
496
497 if (s->numbytes[0] == '\0')
498 return add_finish;
499
500 sp.offset = OFF_FROM_HEADER (s->offset);
501 sp.numbytes = OFF_FROM_HEADER (s->numbytes);
502
503 if (sp.offset < 0 || sp.numbytes < 0
504 || INT_ADD_OVERFLOW (sp.offset, sp.numbytes)
505 || file->stat_info->stat.st_size < sp.offset + sp.numbytes
506 || file->stat_info->archive_file_size < 0)
507 return add_fail;
508
509 sparse_add_map (file->stat_info, &sp);
510
511 return add_ok;
512 }
513
514
515
516 static gboolean
517 oldgnu_sparse_member_p (struct tar_sparse_file *file)
518 {
519 (void) file;
520
521 return current_header->header.typeflag == GNUTYPE_SPARSE;
522 }
523
524
525
526 static gboolean
527 oldgnu_fixup_header (struct tar_sparse_file *file)
528 {
529
530
531 off_t realsize;
532
533 realsize = OFF_FROM_HEADER (current_header->oldgnu_header.realsize);
534 file->stat_info->archive_file_size = file->stat_info->stat.st_size;
535 file->stat_info->stat.st_size = MAX (0, realsize);
536
537 return (realsize >= 0);
538 }
539
540
541
542
543
544
545 static gboolean
546 oldgnu_get_sparse_info (tar_super_t * archive, struct tar_sparse_file *file)
547 {
548 size_t i;
549 union block *h = current_header;
550 gboolean ext_p;
551 enum oldgnu_add_status rc = add_fail;
552
553 if (file->stat_info->sparse_map != NULL)
554 g_array_set_size (file->stat_info->sparse_map, 0);
555
556 for (i = 0; i < SPARSES_IN_OLDGNU_HEADER; i++)
557 {
558 rc = oldgnu_add_sparse (file, &h->oldgnu_header.sp[i]);
559 if (rc != add_ok)
560 break;
561 }
562
563 for (ext_p = h->oldgnu_header.isextended != 0; rc == add_ok && ext_p;
564 ext_p = h->sparse_header.isextended != 0)
565 {
566 h = tar_find_next_block (archive);
567 if (h == NULL)
568 return FALSE;
569
570 tar_set_next_block_after (h);
571
572 for (i = 0; i < SPARSES_IN_SPARSE_HEADER && rc == add_ok; i++)
573 rc = oldgnu_add_sparse (file, &h->sparse_header.sp[i]);
574 }
575
576 return (rc != add_fail);
577 }
578
579
580
581 static gboolean
582 star_sparse_member_p (struct tar_sparse_file *file)
583 {
584 (void) file;
585
586 return current_header->header.typeflag == GNUTYPE_SPARSE;
587 }
588
589
590
591 static gboolean
592 star_fixup_header (struct tar_sparse_file *file)
593 {
594
595
596 off_t realsize;
597
598 realsize = OFF_FROM_HEADER (current_header->star_in_header.realsize);
599 file->stat_info->archive_file_size = file->stat_info->stat.st_size;
600 file->stat_info->stat.st_size = MAX (0, realsize);
601
602 return (realsize >= 0);
603 }
604
605
606
607
608
609
610 static gboolean
611 star_get_sparse_info (tar_super_t * archive, struct tar_sparse_file *file)
612 {
613 size_t i;
614 union block *h = current_header;
615 gboolean ext_p = TRUE;
616 enum oldgnu_add_status rc = add_ok;
617
618 if (file->stat_info->sparse_map != NULL)
619 g_array_set_size (file->stat_info->sparse_map, 0);
620
621 if (h->star_in_header.prefix[0] == '\0' && h->star_in_header.sp[0].offset[10] != '\0')
622 {
623
624 for (i = 0; i < SPARSES_IN_STAR_HEADER; i++)
625 {
626 rc = oldgnu_add_sparse (file, &h->star_in_header.sp[i]);
627 if (rc != add_ok)
628 break;
629 }
630
631 ext_p = h->star_in_header.isextended != 0;
632 }
633
634 for (; rc == add_ok && ext_p; ext_p = h->star_ext_header.isextended != 0)
635 {
636 h = tar_find_next_block (archive);
637 if (h == NULL)
638 return FALSE;
639
640 tar_set_next_block_after (h);
641
642 for (i = 0; i < SPARSES_IN_STAR_EXT_HEADER && rc == add_ok; i++)
643 rc = oldgnu_add_sparse (file, &h->star_ext_header.sp[i]);
644
645 file->dumped_size += BLOCKSIZE;
646 }
647
648 return (rc != add_fail);
649 }
650
651
652
653 static gboolean
654 pax_sparse_member_p (struct tar_sparse_file *file)
655 {
656 return file->stat_info->sparse_map != NULL && file->stat_info->sparse_map->len > 0
657 && file->stat_info->sparse_major > 0;
658 }
659
660
661
662 static gboolean
663 pax_decode_header (tar_super_t * archive, struct tar_sparse_file *file)
664 {
665 if (file->stat_info->sparse_major > 0)
666 {
667 uintmax_t u;
668 char nbuf[UINTMAX_STRSIZE_BOUND];
669 union block *blk;
670 char *p;
671 size_t sparse_map_len;
672 size_t i;
673 off_t start;
674
675 start = tar_current_block_ordinal (archive);
676 tar_set_next_block_after (current_header);
677 blk = tar_find_next_block (archive);
678 if (blk == NULL)
679
680 return FALSE;
681 p = blk->buffer;
682 COPY_BUF (archive, blk, nbuf, p);
683
684 if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t)))
685 {
686
687 return FALSE;
688 }
689
690 if (file->stat_info->sparse_map == NULL)
691 file->stat_info->sparse_map =
692 g_array_sized_new (FALSE, FALSE, sizeof (struct sp_array), u);
693 else
694 g_array_set_size (file->stat_info->sparse_map, u);
695
696 sparse_map_len = u;
697
698 for (i = 0; i < sparse_map_len; i++)
699 {
700 struct sp_array sp;
701
702 COPY_BUF (archive, blk, nbuf, p);
703 if (!decode_num (&u, nbuf, TYPE_MAXIMUM (off_t)))
704 {
705
706 return FALSE;
707 }
708 sp.offset = u;
709 COPY_BUF (archive, blk, nbuf, p);
710 if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t)) || INT_ADD_OVERFLOW (sp.offset, u)
711 || (uintmax_t) file->stat_info->stat.st_size < sp.offset + u)
712 {
713
714 return FALSE;
715 }
716 sp.numbytes = u;
717 sparse_add_map (file->stat_info, &sp);
718 }
719
720 tar_set_next_block_after (blk);
721
722 file->dumped_size += BLOCKSIZE * (tar_current_block_ordinal (archive) - start);
723 }
724
725 return TRUE;
726 }
727
728
729
730
731
732 gboolean
733 tar_sparse_member_p (tar_super_t * archive, struct tar_stat_info * st)
734 {
735 struct tar_sparse_file file;
736
737 if (!sparse_init (archive, &file))
738 return FALSE;
739
740 file.stat_info = st;
741 return sparse_member_p (&file);
742 }
743
744
745
746 gboolean
747 tar_sparse_fixup_header (tar_super_t * archive, struct tar_stat_info * st)
748 {
749 struct tar_sparse_file file;
750
751 if (!sparse_init (archive, &file))
752 return FALSE;
753
754 file.stat_info = st;
755 return sparse_fixup_header (&file);
756 }
757
758
759
760 enum dump_status
761 tar_sparse_skip_file (tar_super_t * archive, struct tar_stat_info *st)
762 {
763 gboolean rc = TRUE;
764 struct tar_sparse_file file;
765
766 if (!sparse_init (archive, &file))
767 return dump_status_not_implemented;
768
769 file.stat_info = st;
770 file.fd = -1;
771
772 rc = sparse_decode_header (archive, &file);
773 (void) tar_skip_file (archive, file.stat_info->archive_file_size - file.dumped_size);
774 return (sparse_done (&file) && rc) ? dump_status_ok : dump_status_short;
775 }
776
777