1 /* POSIX extended headers for tar.
2 
3    Copyright (C) 2003-2021 Free Software Foundation, Inc.
4 
5    This file is part of GNU tar.
6 
7    GNU tar is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    GNU tar is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include <system.h>
21 
22 #include <fnmatch.h>
23 #include <hash.h>
24 #include <inttostr.h>
25 #include <quotearg.h>
26 
27 #include "common.h"
28 
29 static void xheader_init (struct xheader *xhdr);
30 static bool xheader_protected_pattern_p (char const *pattern);
31 static bool xheader_protected_keyword_p (char const *keyword);
32 static void xheader_set_single_keyword (char *) __attribute__ ((noreturn));
33 
34 /* Used by xheader_finish() */
35 static void code_string (char const *string, char const *keyword,
36 			 struct xheader *xhdr);
37 
38 /* Number of global headers written so far. */
39 static size_t global_header_count;
40 /* FIXME: Possibly it should be reset after changing the volume.
41    POSIX %n specification says that it is expanded to the sequence
42    number of current global header in *the* archive. However, for
43    multi-volume archives this will yield duplicate header names
44    in different volumes, which I'd like to avoid. The best way
45    to solve this would be to use per-archive header count as required
46    by POSIX *and* set globexthdr.name to, say,
47    $TMPDIR/GlobalHead.%p.$NUMVOLUME.%n.
48 
49    However it should wait until buffer.c is finally rewritten */
50 
51 
52 /* Interface functions to obstacks */
53 
54 static void
x_obstack_grow(struct xheader * xhdr,const char * ptr,size_t length)55 x_obstack_grow (struct xheader *xhdr, const char *ptr, size_t length)
56 {
57   obstack_grow (xhdr->stk, ptr, length);
58   xhdr->size += length;
59 }
60 
61 static void
x_obstack_1grow(struct xheader * xhdr,char c)62 x_obstack_1grow (struct xheader *xhdr, char c)
63 {
64   obstack_1grow (xhdr->stk, c);
65   xhdr->size++;
66 }
67 
68 static void
x_obstack_blank(struct xheader * xhdr,size_t length)69 x_obstack_blank (struct xheader *xhdr, size_t length)
70 {
71   obstack_blank (xhdr->stk, length);
72   xhdr->size += length;
73 }
74 
75 
76 /* Keyword options */
77 
78 struct keyword_list
79 {
80   struct keyword_list *next;
81   char *pattern;
82   char *value;
83 };
84 
85 
86 /* List of keyword patterns set by delete= option */
87 static struct keyword_list *keyword_pattern_list;
88 
89 /* List of keyword/value pairs set by 'keyword=value' option */
90 static struct keyword_list *keyword_global_override_list;
91 
92 /* List of keyword/value pairs set by 'keyword:=value' option */
93 static struct keyword_list *keyword_override_list;
94 
95 /* List of keyword/value pairs decoded from the last 'g' type header */
96 static struct keyword_list *global_header_override_list;
97 
98 /* Template for the name field of an 'x' type header */
99 static char *exthdr_name;
100 
101 static char *exthdr_mtime_option;
102 static time_t exthdr_mtime;
103 
104 /* Template for the name field of a 'g' type header */
105 static char *globexthdr_name;
106 
107 static char *globexthdr_mtime_option;
108 static time_t globexthdr_mtime;
109 
110 bool
xheader_keyword_deleted_p(const char * kw)111 xheader_keyword_deleted_p (const char *kw)
112 {
113   struct keyword_list *kp;
114 
115   for (kp = keyword_pattern_list; kp; kp = kp->next)
116     if (fnmatch (kp->pattern, kw, 0) == 0)
117       return true;
118   return false;
119 }
120 
121 static bool
xheader_keyword_override_p(const char * keyword)122 xheader_keyword_override_p (const char *keyword)
123 {
124   struct keyword_list *kp;
125 
126   for (kp = keyword_override_list; kp; kp = kp->next)
127     if (strcmp (kp->pattern, keyword) == 0)
128       return true;
129   return false;
130 }
131 
132 static void
xheader_list_append(struct keyword_list ** root,char const * kw,char const * value)133 xheader_list_append (struct keyword_list **root, char const *kw,
134 		     char const *value)
135 {
136   struct keyword_list *kp = xmalloc (sizeof *kp);
137   kp->pattern = xstrdup (kw);
138   kp->value = value ? xstrdup (value) : NULL;
139   kp->next = *root;
140   *root = kp;
141 }
142 
143 static void
xheader_list_destroy(struct keyword_list ** root)144 xheader_list_destroy (struct keyword_list **root)
145 {
146   if (root)
147     {
148       struct keyword_list *kw = *root;
149       while (kw)
150 	{
151 	  struct keyword_list *next = kw->next;
152 	  free (kw->pattern);
153 	  free (kw->value);
154 	  free (kw);
155 	  kw = next;
156 	}
157       *root = NULL;
158     }
159 }
160 
161 static void
xheader_set_single_keyword(char * kw)162 xheader_set_single_keyword (char *kw)
163 {
164   USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet implemented"), kw));
165 }
166 
167 static void
assign_time_option(char ** sval,time_t * tval,const char * input)168 assign_time_option (char **sval, time_t *tval, const char *input)
169 {
170   char *p;
171   struct timespec t = decode_timespec (input, &p, false);
172   if (! valid_timespec (t) || *p)
173     ERROR ((0, 0, _("Time stamp is out of allowed range")));
174   else
175     {
176       *tval = t.tv_sec;
177       assign_string (sval, input);
178     }
179 }
180 
181 static void
xheader_set_keyword_equal(char * kw,char * eq)182 xheader_set_keyword_equal (char *kw, char *eq)
183 {
184   bool global = true;
185   char *p = eq;
186 
187   if (eq == kw)
188     USAGE_ERROR ((0, 0, _("Malformed pax option: %s"), quote (kw)));
189 
190   if (eq[-1] == ':')
191     {
192       p--;
193       global = false;
194     }
195 
196   while (p > kw && isspace ((unsigned char) *p))
197     p--;
198 
199   *p = 0;
200 
201   for (p = eq + 1; *p && isspace ((unsigned char) *p); p++)
202     ;
203 
204   if (strcmp (kw, "delete") == 0)
205     {
206       if (xheader_protected_pattern_p (p))
207 	USAGE_ERROR ((0, 0, _("Pattern %s cannot be used"), quote (p)));
208       xheader_list_append (&keyword_pattern_list, p, NULL);
209     }
210   else if (strcmp (kw, "exthdr.name") == 0)
211     assign_string (&exthdr_name, p);
212   else if (strcmp (kw, "globexthdr.name") == 0)
213     assign_string (&globexthdr_name, p);
214   else if (strcmp (kw, "exthdr.mtime") == 0)
215     assign_time_option (&exthdr_mtime_option, &exthdr_mtime, p);
216   else if (strcmp (kw, "globexthdr.mtime") == 0)
217     assign_time_option (&globexthdr_mtime_option, &globexthdr_mtime, p);
218   else
219     {
220       if (xheader_protected_keyword_p (kw))
221 	USAGE_ERROR ((0, 0, _("Keyword %s cannot be overridden"), kw));
222       if (global)
223 	xheader_list_append (&keyword_global_override_list, kw, p);
224       else
225 	xheader_list_append (&keyword_override_list, kw, p);
226     }
227 }
228 
229 void
xheader_set_option(char * string)230 xheader_set_option (char *string)
231 {
232   char *token;
233   for (token = strtok (string, ","); token; token = strtok (NULL, ","))
234     {
235       char *p = strchr (token, '=');
236       if (!p)
237 	xheader_set_single_keyword (token);
238       else
239 	xheader_set_keyword_equal (token, p);
240     }
241 }
242 
243 /*
244     string Includes:          Replaced By:
245      %d                       The directory name of the file,
246                               equivalent to the result of the
247                               dirname utility on the translated
248                               file name.
249      %f                       The filename of the file, equivalent
250                               to the result of the basename
251                               utility on the translated file name.
252      %p                       The process ID of the pax process.
253      %n                       The value of the 3rd argument.
254      %%                       A '%' character. */
255 
256 char *
xheader_format_name(struct tar_stat_info * st,const char * fmt,size_t n)257 xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
258 {
259   char *buf;
260   size_t len;
261   char *q;
262   const char *p;
263   char *dirp = NULL;
264   char *dir = NULL;
265   char *base = NULL;
266   char pidbuf[UINTMAX_STRSIZE_BOUND];
267   char const *pptr = NULL;
268   char nbuf[UINTMAX_STRSIZE_BOUND];
269   char const *nptr = NULL;
270 
271   len = 0;
272   for (p = fmt; *p; p++)
273     {
274       if (*p == '%' && p[1])
275 	{
276 	  switch (*++p)
277 	    {
278 	    case '%':
279 	      len++;
280 	      break;
281 
282 	    case 'd':
283 	      if (st)
284 		{
285 		  if (!dirp)
286 		    dirp = dir_name (st->orig_file_name);
287 		  dir = safer_name_suffix (dirp, false, absolute_names_option);
288 		  len += strlen (dir);
289 		}
290 	      break;
291 
292 	    case 'f':
293 	      if (st)
294 		{
295 		  base = last_component (st->orig_file_name);
296 		  len += strlen (base);
297 		}
298 	      break;
299 
300 	    case 'p':
301 	      pptr = umaxtostr (getpid (), pidbuf);
302 	      len += pidbuf + sizeof pidbuf - 1 - pptr;
303 	      break;
304 
305 	    case 'n':
306 	      nptr = umaxtostr (n, nbuf);
307 	      len += nbuf + sizeof nbuf - 1 - nptr;
308 	      break;
309 
310 	    default:
311 	      len += 2;
312 	    }
313 	}
314       else
315 	len++;
316     }
317 
318   buf = xmalloc (len + 1);
319   for (q = buf, p = fmt; *p; )
320     {
321       if (*p == '%')
322 	{
323 	  switch (p[1])
324 	    {
325 	    case '%':
326 	      *q++ = *p++;
327 	      p++;
328 	      break;
329 
330 	    case 'd':
331 	      if (dir)
332 		q = stpcpy (q, dir);
333 	      p += 2;
334 	      break;
335 
336 	    case 'f':
337 	      if (base)
338 		q = stpcpy (q, base);
339 	      p += 2;
340 	      break;
341 
342 	    case 'p':
343 	      q = stpcpy (q, pptr);
344 	      p += 2;
345 	      break;
346 
347 	    case 'n':
348 	      q = stpcpy (q, nptr);
349 	      p += 2;
350 	      break;
351 
352 
353 	    default:
354 	      *q++ = *p++;
355 	      if (*p)
356 		*q++ = *p++;
357 	    }
358 	}
359       else
360 	*q++ = *p++;
361     }
362 
363   free (dirp);
364 
365   /* Do not allow it to end in a slash */
366   while (q > buf && ISSLASH (q[-1]))
367     q--;
368   *q = 0;
369   return buf;
370 }
371 
372 /* Table of templates for the names of POSIX extended headers.
373    Indexed by the the type of the header (per-file or global)
374    and POSIX compliance mode (0 or q depending on whether
375    POSIXLY_CORRECT environment variable is set. */
376 static const char *header_template[][2] = {
377   /* Individual header templates: */
378   { "%d/PaxHeaders/%f", "%d/PaxHeaders.%p/%f" },
379   /* Global header templates: */
380   { "/GlobalHead.%n", "/GlobalHead.%p.%n" }
381 };
382 /* Indices to the above table */
383 enum {
384   pax_file_header,
385   pax_global_header
386 };
387 /* Return the name for the POSIX extended header T */
388 #define HEADER_TEMPLATE(t) header_template[t][posixly_correct]
389 
390 char *
xheader_xhdr_name(struct tar_stat_info * st)391 xheader_xhdr_name (struct tar_stat_info *st)
392 {
393   if (!exthdr_name)
394     assign_string (&exthdr_name, HEADER_TEMPLATE (pax_file_header));
395   return xheader_format_name (st, exthdr_name, 0);
396 }
397 
398 char *
xheader_ghdr_name(void)399 xheader_ghdr_name (void)
400 {
401   if (!globexthdr_name)
402     {
403       size_t len;
404       const char *global_header_template = HEADER_TEMPLATE (pax_global_header);
405       const char *tmp = getenv ("TMPDIR");
406       if (!tmp)
407 	tmp = "/tmp";
408       len = strlen (tmp) + strlen (global_header_template) + 1;
409       globexthdr_name = xmalloc (len);
410       strcpy(globexthdr_name, tmp);
411       strcat(globexthdr_name, global_header_template);
412     }
413 
414   return xheader_format_name (NULL, globexthdr_name, global_header_count + 1);
415 }
416 
417 void
xheader_write(char type,char * name,time_t t,struct xheader * xhdr)418 xheader_write (char type, char *name, time_t t, struct xheader *xhdr)
419 {
420   union block *header;
421   size_t size;
422   char *p;
423 
424   size = xhdr->size;
425   switch (type)
426     {
427     case XGLTYPE:
428       if (globexthdr_mtime_option)
429 	t = globexthdr_mtime;
430       break;
431 
432     case XHDTYPE:
433       if (exthdr_mtime_option)
434 	t = exthdr_mtime;
435       break;
436     }
437   header = start_private_header (name, size, t);
438   header->header.typeflag = type;
439 
440   simple_finish_header (header);
441 
442   p = xhdr->buffer;
443 
444   do
445     {
446       size_t len;
447 
448       header = find_next_block ();
449       len = BLOCKSIZE;
450       if (len > size)
451 	len = size;
452       memcpy (header->buffer, p, len);
453       if (len < BLOCKSIZE)
454 	memset (header->buffer + len, 0, BLOCKSIZE - len);
455       p += len;
456       size -= len;
457       set_next_block_after (header);
458     }
459   while (size > 0);
460   xheader_destroy (xhdr);
461 
462   if (type == XGLTYPE)
463     global_header_count++;
464 }
465 
466 void
xheader_write_global(struct xheader * xhdr)467 xheader_write_global (struct xheader *xhdr)
468 {
469   if (keyword_global_override_list)
470     {
471       struct keyword_list *kp;
472 
473       xheader_init (xhdr);
474       for (kp = keyword_global_override_list; kp; kp = kp->next)
475 	code_string (kp->value, kp->pattern, xhdr);
476     }
477   if (xhdr->stk)
478     {
479       char *name;
480 
481       xheader_finish (xhdr);
482       name = xheader_ghdr_name ();
483       xheader_write (XGLTYPE, name, start_time.tv_sec, xhdr);
484       free (name);
485     }
486 }
487 
488 /* Forbid modifications of the global extended header */
489 void
xheader_forbid_global(void)490 xheader_forbid_global (void)
491 {
492   if (keyword_global_override_list)
493     USAGE_ERROR ((0, 0, _("can't update global extended header record")));
494 }
495 
496 void
xheader_xattr_init(struct tar_stat_info * st)497 xheader_xattr_init (struct tar_stat_info *st)
498 {
499   st->xattr_map = NULL;
500   st->xattr_map_size = 0;
501 
502   st->acls_a_ptr = NULL;
503   st->acls_a_len = 0;
504   st->acls_d_ptr = NULL;
505   st->acls_d_len = 0;
506   st->cntx_name = NULL;
507 }
508 
509 void
xheader_xattr_free(struct xattr_array * xattr_map,size_t xattr_map_size)510 xheader_xattr_free (struct xattr_array *xattr_map, size_t xattr_map_size)
511 {
512   size_t scan = 0;
513 
514   while (scan < xattr_map_size)
515     {
516       free (xattr_map[scan].xkey);
517       free (xattr_map[scan].xval_ptr);
518 
519       ++scan;
520     }
521   free (xattr_map);
522 }
523 
524 static void
xheader_xattr__add(struct xattr_array ** xattr_map,size_t * xattr_map_size,const char * key,const char * val,size_t len)525 xheader_xattr__add (struct xattr_array **xattr_map,
526 		    size_t *xattr_map_size,
527 		    const char *key, const char *val, size_t len)
528 {
529   size_t pos = (*xattr_map_size)++;
530 
531   *xattr_map = xrealloc (*xattr_map,
532                          *xattr_map_size * sizeof(struct xattr_array));
533   (*xattr_map)[pos].xkey = xstrdup (key);
534   (*xattr_map)[pos].xval_ptr = xmemdup (val, len + 1);
535   (*xattr_map)[pos].xval_len = len;
536 }
537 
538 /* This is reversal function for xattr_encode_keyword.  See comment for
539    xattr_encode_keyword() for more info. */
540 static void
xattr_decode_keyword(char * keyword)541 xattr_decode_keyword (char *keyword)
542 {
543   char *kpr, *kpl; /* keyword pointer left/right */
544   kpr = kpl = keyword;
545 
546   for (;;)
547     {
548       if (*kpr == '%')
549         {
550           if (kpr[1] == '3' && kpr[2] == 'D')
551             {
552               *kpl = '=';
553               kpr += 3;
554               kpl ++;
555               continue;
556             }
557           else if (kpr[1] == '2' && kpr[2] == '5')
558             {
559               *kpl = '%';
560               kpr += 3;
561               kpl ++;
562               continue;
563             }
564         }
565 
566       *kpl = *kpr;
567 
568       if (*kpr == 0)
569         break;
570 
571       kpr++;
572       kpl++;
573     }
574 }
575 
576 void
xheader_xattr_add(struct tar_stat_info * st,const char * key,const char * val,size_t len)577 xheader_xattr_add (struct tar_stat_info *st,
578 		   const char *key, const char *val, size_t len)
579 {
580   size_t klen = strlen (key);
581   char *xkey = xmalloc (strlen("SCHILY.xattr.") + klen + 1);
582   char *tmp = xkey;
583 
584   tmp = stpcpy (tmp, "SCHILY.xattr.");
585   stpcpy (tmp, key);
586 
587   xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len);
588 
589   free (xkey);
590 }
591 
592 void
xheader_xattr_copy(const struct tar_stat_info * st,struct xattr_array ** xattr_map,size_t * xattr_map_size)593 xheader_xattr_copy (const struct tar_stat_info *st,
594 		    struct xattr_array **xattr_map, size_t *xattr_map_size)
595 {
596   size_t scan = 0;
597 
598   *xattr_map = NULL;
599   *xattr_map_size = 0;
600 
601   while (scan < st->xattr_map_size)
602     {
603       char  *key = st->xattr_map[scan].xkey;
604       char  *val = st->xattr_map[scan].xval_ptr;
605       size_t len = st->xattr_map[scan].xval_len;
606 
607       xheader_xattr__add(xattr_map, xattr_map_size, key, val, len);
608 
609       ++scan;
610     }
611 }
612 
613 
614 /* General Interface */
615 
616 #define XHDR_PROTECTED 0x01
617 #define XHDR_GLOBAL    0x02
618 
619 struct xhdr_tab
620 {
621   char const *keyword;
622   void (*coder) (struct tar_stat_info const *, char const *,
623 		 struct xheader *, void const *data);
624   void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t);
625   int flags;
626   bool prefix; /* select handler comparing prefix only */
627 };
628 
629 /* This declaration must be extern, because ISO C99 section 6.9.2
630    prohibits a tentative definition that has both internal linkage and
631    incomplete type.  If we made it static, we'd have to declare its
632    size which would be a maintenance pain; if we put its initializer
633    here, we'd need a boatload of forward declarations, which would be
634    even more of a pain.  */
635 extern struct xhdr_tab const xhdr_tab[];
636 
637 static struct xhdr_tab const *
locate_handler(char const * keyword)638 locate_handler (char const *keyword)
639 {
640   struct xhdr_tab const *p;
641 
642   for (p = xhdr_tab; p->keyword; p++)
643     if (p->prefix)
644       {
645         if (strncmp (p->keyword, keyword, strlen(p->keyword)) == 0)
646           return p;
647       }
648     else
649       {
650         if (strcmp (p->keyword, keyword) == 0)
651           return p;
652       }
653 
654   return NULL;
655 }
656 
657 static bool
xheader_protected_pattern_p(const char * pattern)658 xheader_protected_pattern_p (const char *pattern)
659 {
660   struct xhdr_tab const *p;
661 
662   for (p = xhdr_tab; p->keyword; p++)
663     if (!p->prefix && (p->flags & XHDR_PROTECTED)
664         && fnmatch (pattern, p->keyword, 0) == 0)
665       return true;
666   return false;
667 }
668 
669 static bool
xheader_protected_keyword_p(const char * keyword)670 xheader_protected_keyword_p (const char *keyword)
671 {
672   struct xhdr_tab const *p;
673 
674   for (p = xhdr_tab; p->keyword; p++)
675     if (!p->prefix && (p->flags & XHDR_PROTECTED)
676         && strcmp (p->keyword, keyword) == 0)
677       return true;
678   return false;
679 }
680 
681 /* Decode a single extended header record, advancing *PTR to the next record.
682    Return true on success, false otherwise.  */
683 static bool
decode_record(struct xheader * xhdr,char ** ptr,void (* handler)(void *,char const *,char const *,size_t),void * data)684 decode_record (struct xheader *xhdr,
685 	       char **ptr,
686 	       void (*handler) (void *, char const *, char const *, size_t),
687 	       void *data)
688 {
689   char *start = *ptr;
690   char *p = start;
691   size_t len;
692   char *len_lim;
693   char const *keyword;
694   char *nextp;
695   size_t len_max = xhdr->buffer + xhdr->size - start;
696 
697   while (*p == ' ' || *p == '\t')
698     p++;
699 
700   if (! ISDIGIT (*p))
701     {
702       if (*p)
703 	ERROR ((0, 0, _("Malformed extended header: missing length")));
704       return false;
705     }
706 
707   len = strtoumax (p, &len_lim, 10);
708 
709   if (len_max < len)
710     {
711       int len_len = len_lim - p;
712       ERROR ((0, 0, _("Extended header length %*s is out of range"),
713 	      len_len, p));
714       return false;
715     }
716 
717   nextp = start + len;
718 
719   for (p = len_lim; *p == ' ' || *p == '\t'; p++)
720     continue;
721   if (p == len_lim)
722     {
723       ERROR ((0, 0,
724 	      _("Malformed extended header: missing blank after length")));
725       return false;
726     }
727 
728   keyword = p;
729   p = strchr (p, '=');
730   if (! (p && p < nextp))
731     {
732       ERROR ((0, 0, _("Malformed extended header: missing equal sign")));
733       return false;
734     }
735 
736   if (nextp[-1] != '\n')
737     {
738       ERROR ((0, 0, _("Malformed extended header: missing newline")));
739       return false;
740     }
741 
742   *p = nextp[-1] = '\0';
743   handler (data, keyword, p + 1, nextp - p - 2); /* '=' + trailing '\n' */
744   *p = '=';
745   nextp[-1] = '\n';
746   *ptr = nextp;
747   return true;
748 }
749 
750 static void
run_override_list(struct keyword_list * kp,struct tar_stat_info * st)751 run_override_list (struct keyword_list *kp, struct tar_stat_info *st)
752 {
753   for (; kp; kp = kp->next)
754     {
755       struct xhdr_tab const *t = locate_handler (kp->pattern);
756       if (t)
757 	t->decoder (st, t->keyword, kp->value, strlen (kp->value));
758     }
759 }
760 
761 static void
decx(void * data,char const * keyword,char const * value,size_t size)762 decx (void *data, char const *keyword, char const *value, size_t size)
763 {
764   struct xhdr_tab const *t;
765   struct tar_stat_info *st = data;
766 
767   if (xheader_keyword_deleted_p (keyword)
768       || xheader_keyword_override_p (keyword))
769     return;
770 
771   t = locate_handler (keyword);
772   if (t)
773     t->decoder (st, keyword, value, size);
774   else
775     WARNOPT (WARN_UNKNOWN_KEYWORD,
776 	     (0, 0, _("Ignoring unknown extended header keyword '%s'"),
777 	      keyword));
778 }
779 
780 void
xheader_decode(struct tar_stat_info * st)781 xheader_decode (struct tar_stat_info *st)
782 {
783   run_override_list (keyword_global_override_list, st);
784   run_override_list (global_header_override_list, st);
785 
786   if (st->xhdr.size)
787     {
788       char *p = st->xhdr.buffer + BLOCKSIZE;
789       while (decode_record (&st->xhdr, &p, decx, st))
790 	continue;
791     }
792   run_override_list (keyword_override_list, st);
793 
794   /* The archived (effective) file size is always set directly in tar header
795      field, possibly overridden by "size" extended header - in both cases,
796      result is now decoded in st->stat.st_size */
797   st->archive_file_size = st->stat.st_size;
798 
799   /* The real file size (given by stat()) may be redefined for sparse
800      files in "GNU.sparse.realsize" extended header */
801   if (st->real_size_set)
802     st->stat.st_size = st->real_size;
803 }
804 
805 static void
decg(void * data,char const * keyword,char const * value,size_t size)806 decg (void *data, char const *keyword, char const *value,
807       size_t size __attribute__((unused)))
808 {
809   struct keyword_list **kwl = data;
810   struct xhdr_tab const *tab = locate_handler (keyword);
811   if (tab && (tab->flags & XHDR_GLOBAL))
812     tab->decoder (data, keyword, value, size);
813   else
814     xheader_list_append (kwl, keyword, value);
815 }
816 
817 void
xheader_decode_global(struct xheader * xhdr)818 xheader_decode_global (struct xheader *xhdr)
819 {
820   if (xhdr->size)
821     {
822       char *p = xhdr->buffer + BLOCKSIZE;
823 
824       xheader_list_destroy (&global_header_override_list);
825       while (decode_record (xhdr, &p, decg, &global_header_override_list))
826 	continue;
827     }
828 }
829 
830 static void
xheader_init(struct xheader * xhdr)831 xheader_init (struct xheader *xhdr)
832 {
833   if (!xhdr->stk)
834     {
835       xhdr->stk = xmalloc (sizeof *xhdr->stk);
836       obstack_init (xhdr->stk);
837     }
838 }
839 
840 void
xheader_store(char const * keyword,struct tar_stat_info * st,void const * data)841 xheader_store (char const *keyword, struct tar_stat_info *st,
842 	       void const *data)
843 {
844   struct xhdr_tab const *t;
845 
846   if (st->xhdr.buffer)
847     return;
848   t = locate_handler (keyword);
849   if (!t || !t->coder)
850     return;
851   if (xheader_keyword_deleted_p (keyword))
852     return;
853   xheader_init (&st->xhdr);
854   if (!xheader_keyword_override_p (keyword))
855     t->coder (st, keyword, &st->xhdr, data);
856 }
857 
858 void
xheader_read(struct xheader * xhdr,union block * p,off_t size)859 xheader_read (struct xheader *xhdr, union block *p, off_t size)
860 {
861   size_t j = 0;
862 
863   if (size < 0)
864     size = 0; /* Already diagnosed.  */
865 
866   if (SIZE_MAX - BLOCKSIZE <= size)
867     xalloc_die ();
868 
869   size += BLOCKSIZE;
870   xhdr->size = size;
871   xhdr->buffer = xmalloc (size + 1);
872   xhdr->buffer[size] = '\0';
873 
874   do
875     {
876       size_t len = size;
877 
878       if (len > BLOCKSIZE)
879 	len = BLOCKSIZE;
880 
881       if (!p)
882 	FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
883 
884       memcpy (&xhdr->buffer[j], p->buffer, len);
885       set_next_block_after (p);
886 
887       p = find_next_block ();
888 
889       j += len;
890       size -= len;
891     }
892   while (size > 0);
893 }
894 
895 /* xattr_encode_keyword() substitutes '=' ~~> '%3D' and '%' ~~> '%25'
896    in extended attribute keywords.  This is needed because the '=' character
897    has special purpose in extended attribute header - it splits keyword and
898    value part of header.  If there was the '=' occurrence allowed inside
899    keyword, there would be no unambiguous way how to decode this extended
900    attribute.
901 
902    (http://lists.gnu.org/archive/html/bug-tar/2012-10/msg00017.html)
903  */
904 static char *
xattr_encode_keyword(const char * keyword)905 xattr_encode_keyword(const char *keyword)
906 {
907   static char *encode_buffer = NULL;
908   static size_t encode_buffer_size = 0;
909   size_t bp; /* keyword/buffer pointers */
910 
911   if (!encode_buffer)
912     {
913       encode_buffer_size = 256;
914       encode_buffer = xmalloc (encode_buffer_size);
915     }
916   else
917     *encode_buffer = 0;
918 
919   for (bp = 0; *keyword != 0; ++bp, ++keyword)
920     {
921       char c = *keyword;
922 
923       if (bp + 2 /* enough for URL encoding also.. */ >= encode_buffer_size)
924         {
925           encode_buffer = x2realloc (encode_buffer, &encode_buffer_size);
926         }
927 
928       if (c == '%')
929         {
930           strcpy (encode_buffer + bp, "%25");
931           bp += 2;
932         }
933       else if (c == '=')
934         {
935           strcpy (encode_buffer + bp, "%3D");
936           bp += 2;
937         }
938       else
939         encode_buffer[bp] = c;
940     }
941 
942   encode_buffer[bp] = 0;
943 
944   return encode_buffer;
945 }
946 
947 static void
xheader_print_n(struct xheader * xhdr,char const * keyword,char const * value,size_t vsize)948 xheader_print_n (struct xheader *xhdr, char const *keyword,
949 		 char const *value, size_t vsize)
950 {
951   size_t p;
952   size_t n = 0;
953   char nbuf[UINTMAX_STRSIZE_BOUND];
954   char const *np;
955   size_t len, klen;
956 
957   keyword = xattr_encode_keyword (keyword);
958   klen = strlen (keyword);
959   len = klen + vsize + 3; /* ' ' + '=' + '\n' */
960 
961   do
962     {
963       p = n;
964       np = umaxtostr (len + p, nbuf);
965       n = nbuf + sizeof nbuf - 1 - np;
966     }
967   while (n != p);
968 
969   x_obstack_grow (xhdr, np, n);
970   x_obstack_1grow (xhdr, ' ');
971   x_obstack_grow (xhdr, keyword, klen);
972   x_obstack_1grow (xhdr, '=');
973   x_obstack_grow (xhdr, value, vsize);
974   x_obstack_1grow (xhdr, '\n');
975 }
976 
977 static void
xheader_print(struct xheader * xhdr,char const * keyword,char const * value)978 xheader_print (struct xheader *xhdr, char const *keyword, char const *value)
979 {
980   xheader_print_n (xhdr, keyword, value, strlen (value));
981 }
982 
983 void
xheader_finish(struct xheader * xhdr)984 xheader_finish (struct xheader *xhdr)
985 {
986   struct keyword_list *kp;
987 
988   for (kp = keyword_override_list; kp; kp = kp->next)
989     code_string (kp->value, kp->pattern, xhdr);
990 
991   xhdr->buffer = obstack_finish (xhdr->stk);
992 }
993 
994 void
xheader_destroy(struct xheader * xhdr)995 xheader_destroy (struct xheader *xhdr)
996 {
997   if (xhdr->stk)
998     {
999       obstack_free (xhdr->stk, NULL);
1000       free (xhdr->stk);
1001       xhdr->stk = NULL;
1002     }
1003   else
1004     free (xhdr->buffer);
1005   xhdr->buffer = 0;
1006   xhdr->size = 0;
1007 }
1008 
1009 
1010 /* Buildable strings */
1011 
1012 void
xheader_string_begin(struct xheader * xhdr)1013 xheader_string_begin (struct xheader *xhdr)
1014 {
1015   xhdr->string_length = 0;
1016 }
1017 
1018 void
xheader_string_add(struct xheader * xhdr,char const * s)1019 xheader_string_add (struct xheader *xhdr, char const *s)
1020 {
1021   if (xhdr->buffer)
1022     return;
1023   xheader_init (xhdr);
1024   xhdr->string_length += strlen (s);
1025   x_obstack_grow (xhdr, s, strlen (s));
1026 }
1027 
1028 bool
xheader_string_end(struct xheader * xhdr,char const * keyword)1029 xheader_string_end (struct xheader *xhdr, char const *keyword)
1030 {
1031   uintmax_t len;
1032   uintmax_t p;
1033   uintmax_t n = 0;
1034   size_t size;
1035   char nbuf[UINTMAX_STRSIZE_BOUND];
1036   char const *np;
1037   char *cp;
1038 
1039   if (xhdr->buffer)
1040     return false;
1041   xheader_init (xhdr);
1042 
1043   len = strlen (keyword) + xhdr->string_length + 3; /* ' ' + '=' + '\n' */
1044 
1045   do
1046     {
1047       p = n;
1048       np = umaxtostr (len + p, nbuf);
1049       n = nbuf + sizeof nbuf - 1 - np;
1050     }
1051   while (n != p);
1052 
1053   p = strlen (keyword) + n + 2;
1054   size = p;
1055   if (size != p)
1056     {
1057       ERROR ((0, 0,
1058         _("Generated keyword/value pair is too long (keyword=%s, length=%s)"),
1059 	      keyword, nbuf));
1060       obstack_free (xhdr->stk, obstack_finish (xhdr->stk));
1061       return false;
1062     }
1063   x_obstack_blank (xhdr, p);
1064   x_obstack_1grow (xhdr, '\n');
1065   cp = (char*) obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
1066   memmove (cp + p, cp, xhdr->string_length);
1067   cp = stpcpy (cp, np);
1068   *cp++ = ' ';
1069   cp = stpcpy (cp, keyword);
1070   *cp++ = '=';
1071   return true;
1072 }
1073 
1074 
1075 /* Implementations */
1076 
1077 static void
out_of_range_header(char const * keyword,char const * value,intmax_t minval,uintmax_t maxval)1078 out_of_range_header (char const *keyword, char const *value,
1079 		     intmax_t minval, uintmax_t maxval)
1080 {
1081   char minval_buf[INT_BUFSIZE_BOUND (intmax_t)];
1082   char maxval_buf[UINTMAX_STRSIZE_BOUND];
1083   char *minval_string = imaxtostr (minval, minval_buf);
1084   char *maxval_string = umaxtostr (maxval, maxval_buf);
1085 
1086   /* TRANSLATORS: The first %s is the pax extended header keyword
1087      (atime, gid, etc.).  */
1088   ERROR ((0, 0, _("Extended header %s=%s is out of range %s..%s"),
1089 	  keyword, value, minval_string, maxval_string));
1090 }
1091 
1092 static void
code_string(char const * string,char const * keyword,struct xheader * xhdr)1093 code_string (char const *string, char const *keyword, struct xheader *xhdr)
1094 {
1095   char *outstr;
1096   if (!utf8_convert (true, string, &outstr))
1097     {
1098       /* FIXME: report error */
1099       outstr = xstrdup (string);
1100     }
1101   xheader_print (xhdr, keyword, outstr);
1102   free (outstr);
1103 }
1104 
1105 static void
decode_string(char ** string,char const * arg)1106 decode_string (char **string, char const *arg)
1107 {
1108   if (*string)
1109     {
1110       free (*string);
1111       *string = NULL;
1112     }
1113   if (!utf8_convert (false, arg, string))
1114     {
1115       /* FIXME: report error and act accordingly to --pax invalid=UTF-8 */
1116       assign_string (string, arg);
1117     }
1118 }
1119 
1120 static void
code_time(struct timespec t,char const * keyword,struct xheader * xhdr)1121 code_time (struct timespec t, char const *keyword, struct xheader *xhdr)
1122 {
1123   char buf[TIMESPEC_STRSIZE_BOUND];
1124   xheader_print (xhdr, keyword, code_timespec (t, buf));
1125 }
1126 
1127 static bool
decode_time(struct timespec * ts,char const * arg,char const * keyword)1128 decode_time (struct timespec *ts, char const *arg, char const *keyword)
1129 {
1130   char *arg_lim;
1131   struct timespec t = decode_timespec (arg, &arg_lim, true);
1132 
1133   if (! valid_timespec (t))
1134     {
1135       if (arg < arg_lim && !*arg_lim)
1136 	out_of_range_header (keyword, arg, TYPE_MINIMUM (time_t),
1137 			     TYPE_MAXIMUM (time_t));
1138       else
1139 	ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1140 		keyword, arg));
1141       return false;
1142     }
1143 
1144   *ts = t;
1145   return true;
1146 }
1147 
1148 static void
code_signed_num(uintmax_t value,char const * keyword,intmax_t minval,uintmax_t maxval,struct xheader * xhdr)1149 code_signed_num (uintmax_t value, char const *keyword,
1150 		 intmax_t minval, uintmax_t maxval, struct xheader *xhdr)
1151 {
1152   char sbuf[SYSINT_BUFSIZE];
1153   xheader_print (xhdr, keyword, sysinttostr (value, minval, maxval, sbuf));
1154 }
1155 
1156 static void
code_num(uintmax_t value,char const * keyword,struct xheader * xhdr)1157 code_num (uintmax_t value, char const *keyword, struct xheader *xhdr)
1158 {
1159   code_signed_num (value, keyword, 0, UINTMAX_MAX, xhdr);
1160 }
1161 
1162 static bool
decode_signed_num(intmax_t * num,char const * arg,intmax_t minval,uintmax_t maxval,char const * keyword)1163 decode_signed_num (intmax_t *num, char const *arg,
1164 		   intmax_t minval, uintmax_t maxval,
1165 		   char const *keyword)
1166 {
1167   char *arg_lim;
1168   intmax_t u = strtosysint (arg, &arg_lim, minval, maxval);
1169 
1170   if (errno == EINVAL || *arg_lim)
1171     {
1172       ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1173 	      keyword, arg));
1174       return false;
1175     }
1176 
1177   if (errno == ERANGE)
1178     {
1179       out_of_range_header (keyword, arg, minval, maxval);
1180       return false;
1181     }
1182 
1183   *num = u;
1184   return true;
1185 }
1186 
1187 static bool
decode_num(uintmax_t * num,char const * arg,uintmax_t maxval,char const * keyword)1188 decode_num (uintmax_t *num, char const *arg, uintmax_t maxval,
1189 	    char const *keyword)
1190 {
1191   intmax_t i;
1192   if (! decode_signed_num (&i, arg, 0, maxval, keyword))
1193     return false;
1194   *num = i;
1195   return true;
1196 }
1197 
1198 static void
dummy_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1199 dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)),
1200 	     char const *keyword __attribute__ ((unused)),
1201 	     struct xheader *xhdr __attribute__ ((unused)),
1202 	     void const *data __attribute__ ((unused)))
1203 {
1204 }
1205 
1206 static void
dummy_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1207 dummy_decoder (struct tar_stat_info *st __attribute__ ((unused)),
1208 	       char const *keyword __attribute__ ((unused)),
1209 	       char const *arg __attribute__ ((unused)),
1210 	       size_t size __attribute__((unused)))
1211 {
1212 }
1213 
1214 static void
atime_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1215 atime_coder (struct tar_stat_info const *st, char const *keyword,
1216 	     struct xheader *xhdr, void const *data __attribute__ ((unused)))
1217 {
1218   code_time (st->atime, keyword, xhdr);
1219 }
1220 
1221 static void
atime_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1222 atime_decoder (struct tar_stat_info *st,
1223 	       char const *keyword,
1224 	       char const *arg,
1225 	       size_t size __attribute__((unused)))
1226 {
1227   struct timespec ts;
1228   if (decode_time (&ts, arg, keyword))
1229     st->atime = ts;
1230 }
1231 
1232 static void
gid_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1233 gid_coder (struct tar_stat_info const *st, char const *keyword,
1234 	   struct xheader *xhdr, void const *data __attribute__ ((unused)))
1235 {
1236   code_signed_num (st->stat.st_gid, keyword,
1237 		   TYPE_MINIMUM (gid_t), TYPE_MAXIMUM (gid_t), xhdr);
1238 }
1239 
1240 static void
gid_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1241 gid_decoder (struct tar_stat_info *st,
1242 	     char const *keyword,
1243 	     char const *arg,
1244 	     size_t size __attribute__((unused)))
1245 {
1246   intmax_t u;
1247   if (decode_signed_num (&u, arg, TYPE_MINIMUM (gid_t),
1248 			 TYPE_MAXIMUM (gid_t), keyword))
1249     st->stat.st_gid = u;
1250 }
1251 
1252 static void
gname_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1253 gname_coder (struct tar_stat_info const *st, char const *keyword,
1254 	     struct xheader *xhdr, void const *data __attribute__ ((unused)))
1255 {
1256   code_string (st->gname, keyword, xhdr);
1257 }
1258 
1259 static void
gname_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1260 gname_decoder (struct tar_stat_info *st,
1261 	       char const *keyword __attribute__((unused)),
1262 	       char const *arg,
1263 	       size_t size __attribute__((unused)))
1264 {
1265   decode_string (&st->gname, arg);
1266 }
1267 
1268 static void
linkpath_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1269 linkpath_coder (struct tar_stat_info const *st, char const *keyword,
1270 		struct xheader *xhdr, void const *data __attribute__ ((unused)))
1271 {
1272   code_string (st->link_name, keyword, xhdr);
1273 }
1274 
1275 static void
linkpath_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1276 linkpath_decoder (struct tar_stat_info *st,
1277 		  char const *keyword __attribute__((unused)),
1278 		  char const *arg,
1279 		  size_t size __attribute__((unused)))
1280 {
1281   decode_string (&st->link_name, arg);
1282 }
1283 
1284 static void
ctime_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1285 ctime_coder (struct tar_stat_info const *st, char const *keyword,
1286 	     struct xheader *xhdr, void const *data __attribute__ ((unused)))
1287 {
1288   code_time (st->ctime, keyword, xhdr);
1289 }
1290 
1291 static void
ctime_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1292 ctime_decoder (struct tar_stat_info *st,
1293 	       char const *keyword,
1294 	       char const *arg,
1295 	       size_t size __attribute__((unused)))
1296 {
1297   struct timespec ts;
1298   if (decode_time (&ts, arg, keyword))
1299     st->ctime = ts;
1300 }
1301 
1302 static void
mtime_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1303 mtime_coder (struct tar_stat_info const *st, char const *keyword,
1304 	     struct xheader *xhdr, void const *data)
1305 {
1306   struct timespec const *mtime = data;
1307   code_time (mtime ? *mtime : st->mtime, keyword, xhdr);
1308 }
1309 
1310 static void
mtime_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1311 mtime_decoder (struct tar_stat_info *st,
1312 	       char const *keyword,
1313 	       char const *arg,
1314 	       size_t size __attribute__((unused)))
1315 {
1316   struct timespec ts;
1317   if (decode_time (&ts, arg, keyword))
1318     st->mtime = ts;
1319 }
1320 
1321 static void
path_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1322 path_coder (struct tar_stat_info const *st, char const *keyword,
1323 	    struct xheader *xhdr, void const *data __attribute__ ((unused)))
1324 {
1325   code_string (st->file_name, keyword, xhdr);
1326 }
1327 
1328 static void
raw_path_decoder(struct tar_stat_info * st,char const * arg)1329 raw_path_decoder (struct tar_stat_info *st, char const *arg)
1330 {
1331   decode_string (&st->orig_file_name, arg);
1332   decode_string (&st->file_name, arg);
1333   st->had_trailing_slash = strip_trailing_slashes (st->file_name);
1334 }
1335 
1336 
1337 static void
path_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1338 path_decoder (struct tar_stat_info *st,
1339 	      char const *keyword __attribute__((unused)),
1340 	      char const *arg,
1341 	      size_t size __attribute__((unused)))
1342 {
1343   if (! st->sparse_name_done)
1344     raw_path_decoder (st, arg);
1345 }
1346 
1347 static void
sparse_path_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1348 sparse_path_decoder (struct tar_stat_info *st,
1349                      char const *keyword __attribute__((unused)),
1350                      char const *arg,
1351                      size_t size __attribute__((unused)))
1352 {
1353   st->sparse_name_done = true;
1354   raw_path_decoder (st, arg);
1355 }
1356 
1357 static void
size_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1358 size_coder (struct tar_stat_info const *st, char const *keyword,
1359 	    struct xheader *xhdr, void const *data __attribute__ ((unused)))
1360 {
1361   code_num (st->stat.st_size, keyword, xhdr);
1362 }
1363 
1364 static void
size_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1365 size_decoder (struct tar_stat_info *st,
1366 	      char const *keyword,
1367 	      char const *arg,
1368 	      size_t size __attribute__((unused)))
1369 {
1370   uintmax_t u;
1371   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1372     st->stat.st_size = u;
1373 }
1374 
1375 static void
uid_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1376 uid_coder (struct tar_stat_info const *st, char const *keyword,
1377 	   struct xheader *xhdr, void const *data __attribute__ ((unused)))
1378 {
1379   code_signed_num (st->stat.st_uid, keyword,
1380 		   TYPE_MINIMUM (uid_t), TYPE_MAXIMUM (uid_t), xhdr);
1381 }
1382 
1383 static void
uid_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1384 uid_decoder (struct tar_stat_info *st,
1385 	     char const *keyword,
1386 	     char const *arg,
1387 	     size_t size __attribute__((unused)))
1388 {
1389   intmax_t u;
1390   if (decode_signed_num (&u, arg, TYPE_MINIMUM (uid_t),
1391 			 TYPE_MAXIMUM (uid_t), keyword))
1392     st->stat.st_uid = u;
1393 }
1394 
1395 static void
uname_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1396 uname_coder (struct tar_stat_info const *st, char const *keyword,
1397 	     struct xheader *xhdr, void const *data __attribute__ ((unused)))
1398 {
1399   code_string (st->uname, keyword, xhdr);
1400 }
1401 
1402 static void
uname_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1403 uname_decoder (struct tar_stat_info *st,
1404 	       char const *keyword __attribute__((unused)),
1405 	       char const *arg,
1406 	       size_t size __attribute__((unused)))
1407 {
1408   decode_string (&st->uname, arg);
1409 }
1410 
1411 static void
sparse_size_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1412 sparse_size_coder (struct tar_stat_info const *st, char const *keyword,
1413 	     struct xheader *xhdr, void const *data)
1414 {
1415   size_coder (st, keyword, xhdr, data);
1416 }
1417 
1418 static void
sparse_size_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1419 sparse_size_decoder (struct tar_stat_info *st,
1420 		     char const *keyword,
1421 		     char const *arg,
1422 		     size_t size __attribute__((unused)))
1423 {
1424   uintmax_t u;
1425   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1426     {
1427       st->real_size_set = true;
1428       st->real_size = u;
1429     }
1430 }
1431 
1432 static void
sparse_numblocks_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1433 sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword,
1434 			struct xheader *xhdr,
1435 			void const *data __attribute__ ((unused)))
1436 {
1437   code_num (st->sparse_map_avail, keyword, xhdr);
1438 }
1439 
1440 static void
sparse_numblocks_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1441 sparse_numblocks_decoder (struct tar_stat_info *st,
1442 			  char const *keyword,
1443 			  char const *arg,
1444 			  size_t size __attribute__((unused)))
1445 {
1446   uintmax_t u;
1447   if (decode_num (&u, arg, SIZE_MAX, keyword))
1448     {
1449       st->sparse_map_size = u;
1450       st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]);
1451       st->sparse_map_avail = 0;
1452     }
1453 }
1454 
1455 static void
sparse_offset_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1456 sparse_offset_coder (struct tar_stat_info const *st, char const *keyword,
1457 		     struct xheader *xhdr, void const *data)
1458 {
1459   size_t const *pi = data;
1460   code_num (st->sparse_map[*pi].offset, keyword, xhdr);
1461 }
1462 
1463 static void
sparse_offset_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1464 sparse_offset_decoder (struct tar_stat_info *st,
1465 		       char const *keyword,
1466 		       char const *arg,
1467 		       size_t size __attribute__((unused)))
1468 {
1469   uintmax_t u;
1470   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1471     {
1472       if (st->sparse_map_avail < st->sparse_map_size)
1473 	st->sparse_map[st->sparse_map_avail].offset = u;
1474       else
1475 	ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1476 		"GNU.sparse.offset", arg));
1477     }
1478 }
1479 
1480 static void
sparse_numbytes_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1481 sparse_numbytes_coder (struct tar_stat_info const *st, char const *keyword,
1482 		       struct xheader *xhdr, void const *data)
1483 {
1484   size_t const *pi = data;
1485   code_num (st->sparse_map[*pi].numbytes, keyword, xhdr);
1486 }
1487 
1488 static void
sparse_numbytes_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1489 sparse_numbytes_decoder (struct tar_stat_info *st,
1490 			 char const *keyword,
1491 			 char const *arg,
1492 			 size_t size __attribute__((unused)))
1493 {
1494   uintmax_t u;
1495   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
1496     {
1497       if (st->sparse_map_avail < st->sparse_map_size)
1498 	st->sparse_map[st->sparse_map_avail++].numbytes = u;
1499       else
1500 	ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1501 		keyword, arg));
1502     }
1503 }
1504 
1505 static void
sparse_map_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1506 sparse_map_decoder (struct tar_stat_info *st,
1507 		    char const *keyword,
1508 		    char const *arg,
1509 		    size_t size __attribute__((unused)))
1510 {
1511   int offset = 1;
1512   struct sp_array e;
1513 
1514   st->sparse_map_avail = 0;
1515   while (1)
1516     {
1517       intmax_t u;
1518       char *delim;
1519 
1520       if (!ISDIGIT (*arg))
1521 	{
1522 	  ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
1523 		  keyword, arg));
1524 	  return;
1525 	}
1526 
1527       errno = 0;
1528       u = strtoimax (arg, &delim, 10);
1529       if (TYPE_MAXIMUM (off_t) < u)
1530 	{
1531 	  u = TYPE_MAXIMUM (off_t);
1532 	  errno = ERANGE;
1533 	}
1534       if (offset)
1535 	{
1536 	  e.offset = u;
1537 	  if (errno == ERANGE)
1538 	    {
1539 	      out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t));
1540 	      return;
1541 	    }
1542 	}
1543       else
1544 	{
1545 	  e.numbytes = u;
1546 	  if (errno == ERANGE)
1547 	    {
1548 	      out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t));
1549 	      return;
1550 	    }
1551 	  if (st->sparse_map_avail < st->sparse_map_size)
1552 	    st->sparse_map[st->sparse_map_avail++] = e;
1553 	  else
1554 	    {
1555 	      ERROR ((0, 0, _("Malformed extended header: excess %s=%s"),
1556 		      keyword, arg));
1557 	      return;
1558 	    }
1559 	}
1560 
1561       offset = !offset;
1562 
1563       if (*delim == 0)
1564 	break;
1565       else if (*delim != ',')
1566 	{
1567 	  ERROR ((0, 0,
1568 		  _("Malformed extended header: invalid %s: unexpected delimiter %c"),
1569 		  keyword, *delim));
1570 	  return;
1571 	}
1572 
1573       arg = delim + 1;
1574     }
1575 
1576   if (!offset)
1577     ERROR ((0, 0,
1578 	    _("Malformed extended header: invalid %s: odd number of values"),
1579 	    keyword));
1580 }
1581 
1582 static void
dumpdir_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1583 dumpdir_coder (struct tar_stat_info const *st, char const *keyword,
1584 	       struct xheader *xhdr, void const *data)
1585 {
1586   xheader_print_n (xhdr, keyword, data, dumpdir_size (data));
1587 }
1588 
1589 static void
dumpdir_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1590 dumpdir_decoder (struct tar_stat_info *st,
1591 		 char const *keyword __attribute__((unused)),
1592 		 char const *arg,
1593 		 size_t size)
1594 {
1595   st->dumpdir = xmalloc (size);
1596   memcpy (st->dumpdir, arg, size);
1597 }
1598 
1599 static void
volume_label_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1600 volume_label_coder (struct tar_stat_info const *st, char const *keyword,
1601 		    struct xheader *xhdr, void const *data)
1602 {
1603   code_string (data, keyword, xhdr);
1604 }
1605 
1606 static void
volume_label_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1607 volume_label_decoder (struct tar_stat_info *st,
1608 		      char const *keyword __attribute__((unused)),
1609 		      char const *arg,
1610 		      size_t size __attribute__((unused)))
1611 {
1612   decode_string (&volume_label, arg);
1613 }
1614 
1615 static void
volume_size_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1616 volume_size_coder (struct tar_stat_info const *st, char const *keyword,
1617 		   struct xheader *xhdr, void const *data)
1618 {
1619   off_t const *v = data;
1620   code_num (*v, keyword, xhdr);
1621 }
1622 
1623 static void
volume_size_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1624 volume_size_decoder (struct tar_stat_info *st,
1625 		     char const *keyword,
1626 		     char const *arg, size_t size)
1627 {
1628   uintmax_t u;
1629   if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
1630     continued_file_size = u;
1631 }
1632 
1633 /* FIXME: Merge with volume_size_coder */
1634 static void
volume_offset_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1635 volume_offset_coder (struct tar_stat_info const *st, char const *keyword,
1636 		     struct xheader *xhdr, void const *data)
1637 {
1638   off_t const *v = data;
1639   code_num (*v, keyword, xhdr);
1640 }
1641 
1642 static void
volume_offset_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1643 volume_offset_decoder (struct tar_stat_info *st,
1644 		       char const *keyword,
1645 		       char const *arg, size_t size)
1646 {
1647   uintmax_t u;
1648   if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword))
1649     continued_file_offset = u;
1650 }
1651 
1652 static void
volume_filename_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1653 volume_filename_decoder (struct tar_stat_info *st,
1654 			 char const *keyword __attribute__((unused)),
1655 			 char const *arg,
1656 			 size_t size __attribute__((unused)))
1657 {
1658   decode_string (&continued_file_name, arg);
1659 }
1660 
1661 static void
xattr_selinux_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1662 xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword,
1663                      struct xheader *xhdr, void const *data)
1664 {
1665   code_string (st->cntx_name, keyword, xhdr);
1666 }
1667 
1668 static void
xattr_selinux_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1669 xattr_selinux_decoder (struct tar_stat_info *st,
1670                        char const *keyword, char const *arg, size_t size)
1671 {
1672   decode_string (&st->cntx_name, arg);
1673 }
1674 
1675 static void
xattr_acls_a_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1676 xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword,
1677                     struct xheader *xhdr, void const *data)
1678 {
1679   xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len);
1680 }
1681 
1682 static void
xattr_acls_a_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1683 xattr_acls_a_decoder (struct tar_stat_info *st,
1684                       char const *keyword, char const *arg, size_t size)
1685 {
1686   st->acls_a_ptr = xmemdup (arg, size + 1);
1687   st->acls_a_len = size;
1688 }
1689 
1690 static void
xattr_acls_d_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1691 xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword,
1692                     struct xheader *xhdr, void const *data)
1693 {
1694   xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len);
1695 }
1696 
1697 static void
xattr_acls_d_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1698 xattr_acls_d_decoder (struct tar_stat_info *st,
1699                       char const *keyword, char const *arg, size_t size)
1700 {
1701   st->acls_d_ptr = xmemdup (arg, size + 1);
1702   st->acls_d_len = size;
1703 }
1704 
1705 static void
xattr_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1706 xattr_coder (struct tar_stat_info const *st, char const *keyword,
1707              struct xheader *xhdr, void const *data)
1708 {
1709   struct xattr_array *xattr_map = st->xattr_map;
1710   const size_t *off = data;
1711   xheader_print_n (xhdr, keyword,
1712                    xattr_map[*off].xval_ptr, xattr_map[*off].xval_len);
1713 }
1714 
1715 static void
xattr_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1716 xattr_decoder (struct tar_stat_info *st,
1717                char const *keyword, char const *arg, size_t size)
1718 {
1719   char *xstr, *xkey;
1720 
1721   /* copy keyword */
1722   size_t klen_raw = strlen (keyword);
1723   xkey = alloca (klen_raw + 1);
1724   memcpy (xkey, keyword, klen_raw + 1) /* including null-terminating */;
1725 
1726   /* copy value */
1727   xstr = alloca (size + 1);
1728   memcpy (xstr, arg, size + 1); /* separator included, for GNU tar '\n' */;
1729 
1730   xattr_decode_keyword (xkey);
1731 
1732   xheader_xattr_add (st, xkey + strlen("SCHILY.xattr."), xstr, size);
1733 }
1734 
1735 static void
sparse_major_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1736 sparse_major_coder (struct tar_stat_info const *st, char const *keyword,
1737 		    struct xheader *xhdr, void const *data)
1738 {
1739   code_num (st->sparse_major, keyword, xhdr);
1740 }
1741 
1742 static void
sparse_major_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1743 sparse_major_decoder (struct tar_stat_info *st,
1744 		      char const *keyword,
1745 		      char const *arg,
1746 		      size_t size)
1747 {
1748   uintmax_t u;
1749   if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
1750     st->sparse_major = u;
1751 }
1752 
1753 static void
sparse_minor_coder(struct tar_stat_info const * st,char const * keyword,struct xheader * xhdr,void const * data)1754 sparse_minor_coder (struct tar_stat_info const *st, char const *keyword,
1755 		      struct xheader *xhdr, void const *data)
1756 {
1757   code_num (st->sparse_minor, keyword, xhdr);
1758 }
1759 
1760 static void
sparse_minor_decoder(struct tar_stat_info * st,char const * keyword,char const * arg,size_t size)1761 sparse_minor_decoder (struct tar_stat_info *st,
1762 		      char const *keyword,
1763 		      char const *arg,
1764 		      size_t size)
1765 {
1766   uintmax_t u;
1767   if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
1768     st->sparse_minor = u;
1769 }
1770 
1771 struct xhdr_tab const xhdr_tab[] = {
1772   { "atime",    atime_coder,    atime_decoder,    0, false },
1773   { "comment",  dummy_coder,    dummy_decoder,    0, false },
1774   { "charset",  dummy_coder,    dummy_decoder,    0, false },
1775   { "ctime",    ctime_coder,    ctime_decoder,    0, false },
1776   { "gid",      gid_coder,      gid_decoder,      0, false },
1777   { "gname",    gname_coder,    gname_decoder,    0, false },
1778   { "linkpath", linkpath_coder, linkpath_decoder, 0, false },
1779   { "mtime",    mtime_coder,    mtime_decoder,    0, false },
1780   { "path",     path_coder,     path_decoder,     0, false },
1781   { "size",     size_coder,     size_decoder,     0, false },
1782   { "uid",      uid_coder,      uid_decoder,      0, false },
1783   { "uname",    uname_coder,    uname_decoder,    0, false },
1784 
1785   /* Sparse file handling */
1786   { "GNU.sparse.name",       path_coder, sparse_path_decoder,
1787     XHDR_PROTECTED, false },
1788   { "GNU.sparse.major",      sparse_major_coder, sparse_major_decoder,
1789     XHDR_PROTECTED, false },
1790   { "GNU.sparse.minor",      sparse_minor_coder, sparse_minor_decoder,
1791     XHDR_PROTECTED, false },
1792   { "GNU.sparse.realsize",   sparse_size_coder, sparse_size_decoder,
1793     XHDR_PROTECTED, false },
1794   { "GNU.sparse.numblocks",  sparse_numblocks_coder, sparse_numblocks_decoder,
1795     XHDR_PROTECTED, false },
1796 
1797   /* tar 1.14 - 1.15.90 keywords. */
1798   { "GNU.sparse.size",       sparse_size_coder, sparse_size_decoder,
1799     XHDR_PROTECTED, false },
1800   /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
1801      headers, and each of them was meaningful. It confilcted with POSIX specs,
1802      which requires that "when extended header records conflict, the last one
1803      given in the header shall take precedence." */
1804   { "GNU.sparse.offset",     sparse_offset_coder, sparse_offset_decoder,
1805     XHDR_PROTECTED, false },
1806   { "GNU.sparse.numbytes",   sparse_numbytes_coder, sparse_numbytes_decoder,
1807     XHDR_PROTECTED, false },
1808   /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
1809   { "GNU.sparse.map",        NULL /* Unused, see pax_dump_header() */,
1810     sparse_map_decoder, 0, false },
1811 
1812   { "GNU.dumpdir",           dumpdir_coder, dumpdir_decoder,
1813     XHDR_PROTECTED, false },
1814 
1815   /* Keeps the tape/volume label. May be present only in the global headers.
1816      Equivalent to GNUTYPE_VOLHDR.  */
1817   { "GNU.volume.label", volume_label_coder, volume_label_decoder,
1818     XHDR_PROTECTED | XHDR_GLOBAL, false },
1819 
1820   /* These may be present in a first global header of the archive.
1821      They provide the same functionality as GNUTYPE_MULTIVOL header.
1822      The GNU.volume.size keeps the real_s_sizeleft value, which is
1823      otherwise kept in the size field of a multivolume header.  The
1824      GNU.volume.offset keeps the offset of the start of this volume,
1825      otherwise kept in oldgnu_header.offset.  */
1826   { "GNU.volume.filename", volume_label_coder, volume_filename_decoder,
1827     XHDR_PROTECTED | XHDR_GLOBAL, false },
1828   { "GNU.volume.size", volume_size_coder, volume_size_decoder,
1829     XHDR_PROTECTED | XHDR_GLOBAL, false },
1830   { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder,
1831     XHDR_PROTECTED | XHDR_GLOBAL, false },
1832 
1833   /* We get the SELinux value from filecon, so add a namespace for SELinux
1834      instead of storing it in SCHILY.xattr.* (which would be RAW). */
1835   { "RHT.security.selinux",
1836     xattr_selinux_coder, xattr_selinux_decoder, 0, false },
1837 
1838   /* ACLs, use the star format... */
1839   { "SCHILY.acl.access",
1840     xattr_acls_a_coder, xattr_acls_a_decoder, 0, false },
1841 
1842   { "SCHILY.acl.default",
1843     xattr_acls_d_coder, xattr_acls_d_decoder, 0, false },
1844 
1845   /* We are storing all extended attributes using this rule even if some of them
1846      were stored by some previous rule (duplicates) -- we just have to make sure
1847      they are restored *only once* during extraction later on. */
1848   { "SCHILY.xattr", xattr_coder, xattr_decoder, 0, true },
1849 
1850   { NULL, NULL, NULL, 0, false }
1851 };
1852