]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
maint: port to Fedora 33
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 28 Feb 2021 00:41:12 +0000 (16:41 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 28 Feb 2021 00:42:49 +0000 (16:42 -0800)
Fedora 33 uses GCC 10.2.1, which is a bit pickier.
* configure.ac: Do not use -Wsystem-headers, as this
runs afoul of netdb.h on Fedora 33.
* gnulib.modules: Add ‘attribute’.
* lib/wordsplit.c (wsnode_new): Return the newly allocated
pointer instead of a boolean, to pacify GCC 10.2.1 which otherwise
complains about use of possibly-null pointers.  All uses changed.
* src/buffer.c (try_new_volume): Don’t assume find_next_block succeeds.
(_write_volume_label): Pacify GCC 10.2.1 with an ‘assume’, since
LABEL must be nonnull here.
* src/common.h (FALLTHROUGH): Remove; now in attribute.h.
Include attribute.h, for ATTRIBUTE_NONNULL.
* src/misc.c (assign_string_or_null): New function,
taking over the old role of assign_string.
(assign_string): Assume VALUE is non-null.
(assign_null): New function, taking over the old
role of assign_string when its VALUE was nonnull.
All callers of assign_string changed to use these functions.
(assign_string_n): Clear *STRING if VALUE is null,
to fix a potential double-free.

configure.ac
gnulib.modules
lib/wordsplit.c
src/buffer.c
src/common.h
src/extract.c
src/misc.c

index 8beba5d13c1d31f1ec02f3a66aa7072fd66fd57a..f9d6c8b3d00e14e43a03754f855124f792bc9cc4 100644 (file)
@@ -112,7 +112,7 @@ if test $ac_cv_lib_error_at_line = no; then
   AC_DEFINE([ENABLE_ERROR_PRINT_PROGNAME],[1],
             [Enable the use of error_print_progname to print program name with error messages.
             See comment to function tar_print_progname in src/tar.c])
-fi  
+fi
 
 # paxutils modules
 tar_PAXUTILS
@@ -162,6 +162,7 @@ if test "$gl_gcc_warnings" = yes; then
   nw="$nw -Winline"                 # It's OK to not inline.
   nw="$nw -Wstrict-overflow"       # It's OK to optimize strictly.
   nw="$nw -Wsuggest-attribute=pure" # Too many warnings for now.
+  nw="$nw -Wsystem-headers"         # Don't let system headers trigger warnings
   nw="$nw -Wstack-protector"
 
   gl_MANYWARN_ALL_GCC([ws])
@@ -173,10 +174,10 @@ if test "$gl_gcc_warnings" = yes; then
   gl_WARN_ADD([-Wno-type-limits])      # It's OK to optimize based on types.
   gl_WARN_ADD([-Wno-unused-parameter]) # Too many warnings for now
   gl_WARN_ADD([-Wno-format-nonliteral])
-  
+
   gl_WARN_ADD([-fdiagnostics-show-option])
   gl_WARN_ADD([-funit-at-a-time])
-  
+
 
   AC_SUBST([WARN_CFLAGS])
 
index 68936094b8d2261a900fb1475c056632518f3286..c290000389f29ee162e318a467d3daf7b3358506 100644 (file)
@@ -23,6 +23,7 @@ areadlinkat-with-size
 argmatch
 argp
 argp-version-etc
+attribute
 backupfile
 closeout
 configmake
index 661a4f8b83eb5fdafdcc9f38478bfb13e5b43d25..28390c5b7d0d523f1564cfe8b5abcf54253f3c10 100644 (file)
@@ -95,7 +95,7 @@ _wsplt_seterr (struct wordsplit *wsp, int ec)
     wordsplit_perror (wsp);
   return ec;
 }
-  
+
 static int
 _wsplt_nomem (struct wordsplit *wsp)
 {
@@ -126,7 +126,7 @@ _wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
                 unsigned flags, int finalize)
 {
   int rc;
-  
+
   wss->ws_delim = wsp->ws_delim;
   wss->ws_debug = wsp->ws_debug;
   wss->ws_error = wsp->ws_error;
@@ -150,7 +150,7 @@ _wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
     }
 
   wss->ws_options = wsp->ws_options;
-  
+
   flags |= WRDSF_DELIM
          | WRDSF_ALLOC_DIE
          | WRDSF_ERROR
@@ -209,7 +209,7 @@ wordsplit_init0 (struct wordsplit *wsp)
 }
 
 char wordsplit_c_escape_tab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
-  
+
 static int
 wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
                unsigned flags)
@@ -282,7 +282,7 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
        {
          wsp->ws_escape[WRDSX_WORD] = wordsplit_c_escape_tab;
          wsp->ws_escape[WRDSX_QUOTE] = wordsplit_c_escape_tab;
-         wsp->ws_options |= WRDSO_OESC_QUOTE | WRDSO_OESC_WORD       
+         wsp->ws_options |= WRDSO_OESC_QUOTE | WRDSO_OESC_WORD
                             | WRDSO_XESC_QUOTE | WRDSO_XESC_WORD;
        }
       else
@@ -292,16 +292,16 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
          wsp->ws_options |= WRDSO_BSKEEP_QUOTE;
        }
     }
-  
+
   wsp->ws_endp = 0;
   wsp->ws_wordi = 0;
 
   if (wsp->ws_flags & WRDSF_REUSE)
     wordsplit_free_nodes (wsp);
   wsp->ws_head = wsp->ws_tail = NULL;
-  
+
   wordsplit_init0 (wsp);
-  
+
   return 0;
 }
 
@@ -424,14 +424,13 @@ wsnode_len (struct wordsplit_node *p)
     return p->v.segm.end - p->v.segm.beg;
 }
 
-static int
-wsnode_new (struct wordsplit *wsp, struct wordsplit_node **pnode)
+static struct wordsplit_node *
+wsnode_new (struct wordsplit *wsp)
 {
   struct wordsplit_node *node = calloc (1, sizeof (*node));
   if (!node)
-    return _wsplt_nomem (wsp);
-  *pnode = node;
-  return 0;
+    _wsplt_nomem (wsp);
+  return node;
 }
 
 static void
@@ -527,14 +526,11 @@ wsnode_insert (struct wordsplit *wsp, struct wordsplit_node *node,
 static int
 wordsplit_add_segm (struct wordsplit *wsp, size_t beg, size_t end, int flg)
 {
-  struct wordsplit_node *node;
-  int rc;
-
   if (end == beg && !(flg & _WSNF_EMPTYOK))
     return 0;
-  rc = wsnode_new (wsp, &node);
-  if (rc)
-    return rc;
+  struct wordsplit_node *node = wsnode_new (wsp);
+  if (!node)
+    return 1;
   node->flags = flg & ~(_WSNF_WORD | _WSNF_EMPTYOK);
   node->v.segm.beg = beg;
   node->v.segm.end = end;
@@ -587,7 +583,7 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
 
   if (!(node->flags & _WSNF_JOIN))
     return 0;
-  
+
   for (p = node; p && (p->flags & _WSNF_JOIN); p = p->next)
     {
       len += wsnode_len (p);
@@ -717,7 +713,7 @@ wordsplit_finish (struct wordsplit *wsp)
 
      Nodes of type _WSNF_DELIM get inserted to the node list if either
      WRDSF_RETURN_DELIMS flag or WRDSO_MAXWORDS option is set.
-     
+
      The following cases should be distinguished:
 
      1. If both WRDSF_SQUEEZE_DELIMS and WRDSF_RETURN_DELIMS are set, compress
@@ -781,7 +777,7 @@ wordsplit_finish (struct wordsplit *wsp)
              continue;
            }
        }
-      else 
+      else
        {
          if (delim)
            {
@@ -900,11 +896,11 @@ node_split_prefix (struct wordsplit *wsp,
                   struct wordsplit_node *node,
                   size_t beg, size_t len, int flg)
 {
-  struct wordsplit_node *newnode;
 
   if (len == 0)
     return 0;
-  if (wsnode_new (wsp, &newnode))
+  struct wordsplit_node *newnode = wsnode_new (wsp);
+  if (!newnode)
     return 1;
   wsnode_insert (wsp, newnode, *ptail, 0);
   if (node->flags & _WSNF_WORD)
@@ -958,7 +954,7 @@ find_closing_paren (const char *str, size_t i, size_t len, size_t *poff,
                  break;
                }
              break;
-             
+
            case '"':
              state = st_dquote;
              break;
@@ -1038,7 +1034,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
 {
   int n = (wsp->ws_flags & WRDSF_ENV_KV) ? 2 : 1;
   char *v;
-  
+
   if (wsp->ws_envidx + n >= wsp->ws_envsiz)
     {
       size_t sz;
@@ -1055,7 +1051,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
                  for (; wsp->ws_env[i]; i++)
                    ;
                }
-             
+
              sz = i + n + 1;
 
              newenv = calloc (sz, sizeof(newenv[0]));
@@ -1075,7 +1071,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
                    }
                }
              newenv[j] = NULL;
-             
+
              wsp->ws_envbuf = newenv;
              wsp->ws_envidx = i;
              wsp->ws_envsiz = sz;
@@ -1104,7 +1100,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
          wsp->ws_env = (const char**) wsp->ws_envbuf;
        }
     }
-  
+
   if (wsp->ws_flags & WRDSF_ENV_KV)
     {
       /* A key-value pair environment */
@@ -1149,7 +1145,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
   const char *start = str - 1;
   int rc;
   struct wordsplit ws;
-  
+
   if (ISVARBEG (str[0]))
     {
       for (i = 1; i < len; i++)
@@ -1166,7 +1162,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
          if (str[i] == ':')
            {
              size_t j;
-             
+
              defstr = str + i + 1;
              if (find_closing_paren (str, i + 1, len, &j, "{}"))
                return _wsplt_seterr (wsp, WRDSE_CBRACE);
@@ -1182,7 +1178,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
          else if (strchr ("-+?=", str[i]))
            {
              size_t j;
-             
+
              defstr = str + i;
              if (find_closing_paren (str, i, len, &j, "{}"))
                return _wsplt_seterr (wsp, WRDSE_CBRACE);
@@ -1195,7 +1191,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
     }
   else
     {
-      if (wsnode_new (wsp, &newnode))
+      newnode = wsnode_new (wsp);
+      if (!newnode)
        return 1;
       wsnode_insert (wsp, newnode, *ptail, 0);
       *ptail = newnode;
@@ -1247,7 +1244,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
          rc = WRDSE_UNDEF;
        }
     }
-  
+
   switch (rc)
     {
     case WRDSE_OK:
@@ -1267,7 +1264,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
          wordsplit_free (&ws);
        }
       break;
-      
+
     case WRDSE_UNDEF:
       if (defstr)
        {
@@ -1287,11 +1284,11 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
              value = ws.ws_wordv[0];
              ws.ws_wordv[0] = NULL;
              wordsplit_free (&ws);
-             
+
              if (defstr[-1] == '=')
                wsplt_assign_var (wsp, str, i, value);
            }
-         else 
+         else
            {
              if (*defstr == '?')
                {
@@ -1339,7 +1336,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
            }
        }
       break;
-      
+
     case WRDSE_NOSPACE:
       return _wsplt_nomem (wsp);
 
@@ -1357,7 +1354,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
     {
       if (flg & _WSNF_QUOTE)
        {
-         if (wsnode_new (wsp, &newnode))
+         newnode = wsnode_new (wsp);
+         if (!newnode)
            {
              free (value);
              return 1;
@@ -1371,7 +1369,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
        {
          free (value);
          /* Empty string is a special case */
-         if (wsnode_new (wsp, &newnode))
+         newnode = wsnode_new (wsp);
+         if (!newnode)
            return 1;
          wsnode_insert (wsp, newnode, *ptail, 0);
          *ptail = newnode;
@@ -1381,7 +1380,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
        {
          struct wordsplit ws;
          int rc;
-         
+
          rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
                                WRDSF_NOVAR | WRDSF_NOCMD |
                                WRDSF_QUOTE
@@ -1404,7 +1403,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
     {
       size_t size = *pend - start + 1;
 
-      if (wsnode_new (wsp, &newnode))
+      newnode = wsnode_new (wsp);
+      if (!newnode)
        return 1;
       wsnode_insert (wsp, newnode, *ptail, 0);
       *ptail = newnode;
@@ -1417,7 +1417,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
     }
   else
     {
-      if (wsnode_new (wsp, &newnode))
+      newnode = wsnode_new (wsp);
+      if (!newnode)
        return 1;
       wsnode_insert (wsp, newnode, *ptail, 0);
       *ptail = newnode;
@@ -1486,7 +1487,7 @@ node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
     }
   return 0;
 }
-  
+
 /* Remove NULL nodes from the list */
 static void
 wsnode_nullelim (struct wordsplit *wsp)
@@ -1539,7 +1540,7 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
   size_t j;
   char *value;
   struct wordsplit_node *newnode;
-  
+
   str++;
   len--;
 
@@ -1566,7 +1567,7 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
     }
   else
     rc = wsp->ws_command (&value, str, j, NULL, wsp->ws_closure);
-  
+
   if (rc == WRDSE_NOSPACE)
     return _wsplt_nomem (wsp);
   else if (rc)
@@ -1585,7 +1586,8 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
     {
       if (flg & _WSNF_QUOTE)
        {
-         if (wsnode_new (wsp, &newnode))
+         newnode = wsnode_new (wsp);
+         if (!newnode)
            return 1;
          wsnode_insert (wsp, newnode, *ptail, 0);
          *ptail = newnode;
@@ -1596,7 +1598,8 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
        {
          free (value);
          /* Empty string is a special case */
-         if (wsnode_new (wsp, &newnode))
+         newnode = wsnode_new (wsp);
+         if (!newnode)
            return 1;
          wsnode_insert (wsp, newnode, *ptail, 0);
          *ptail = newnode;
@@ -1627,7 +1630,8 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
     }
   else
     {
-      if (wsnode_new (wsp, &newnode))
+      newnode = wsnode_new (wsp);
+      if (!newnode)
        return 1;
       wsnode_insert (wsp, newnode, *ptail, 0);
       *ptail = newnode;
@@ -1674,13 +1678,13 @@ wordsplit_trimws (struct wordsplit *wsp)
            ;
          p->v.segm.beg = n;
        }
-      
+
       while (p->next && (p->flags & _WSNF_JOIN))
        p = p->next;
-      
+
       if (p->flags & _WSNF_QUOTE)
        continue;
-      
+
       /* Trim trailing whitespace */
       for (n = p->v.segm.end;
           n > p->v.segm.beg && ISWS (wsp->ws_input[n - 1]); n--);
@@ -1699,7 +1703,7 @@ wordsplit_tildexpand (struct wordsplit *wsp)
   struct wordsplit_node *p;
   char *uname = NULL;
   size_t usize = 0;
-  
+
   for (p = wsp->ws_head; p; p = p->next)
     {
       const char *str;
@@ -1714,7 +1718,7 @@ wordsplit_tildexpand (struct wordsplit *wsp)
          size_t slen = wsnode_len (p);
          struct passwd *pw;
          char *newstr;
-         
+
          for (i = 1; i < slen && str[i] != '/'; i++)
            ;
          if (i == slen)
@@ -1788,7 +1792,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
   if (wsp->ws_options & WRDSO_DOTGLOB)
     flags = GLOB_PERIOD;
 #endif
-  
+
   for (p = wsp->ws_head; p; p = next)
     {
       const char *str;
@@ -1807,23 +1811,23 @@ wordsplit_pathexpand (struct wordsplit *wsp)
          glob_t g;
          struct wordsplit_node *prev;
          char *pattern;
-         
+
          pattern = malloc (slen + 1);
          if (!pattern)
            return _wsplt_nomem (wsp);
          memcpy (pattern, str, slen);
          pattern[slen] = 0;
-      
+
          switch (glob (pattern, flags, NULL, &g))
            {
            case 0:
              free (pattern);
              break;
-             
+
            case GLOB_NOSPACE:
              free (pattern);
              return _wsplt_nomem (wsp);
-             
+
            case GLOB_NOMATCH:
              if (wsp->ws_options & WRDSO_NULLGLOB)
                {
@@ -1846,7 +1850,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
                }
              free (pattern);
              continue;
-             
+
            default:
              free (pattern);
              return _wsplt_seterr (wsp, WRDSE_GLOBERR);
@@ -1855,10 +1859,10 @@ wordsplit_pathexpand (struct wordsplit *wsp)
          prev = p;
          for (i = 0; i < g.gl_pathc; i++)
            {
-             struct wordsplit_node *newnode;
+             struct wordsplit_node *newnode = wsnode_new (wsp);
              char *newstr;
-             
-             if (wsnode_new (wsp, &newnode))
+
+             if (!newnode)
                return 1;
              newstr = strdup (g.gl_pathv[i]);
              if (!newstr)
@@ -1975,7 +1979,7 @@ scan_word (struct wordsplit *wsp, size_t start, int consume_all)
   int join = 0;
   unsigned flags = 0;
   struct wordsplit_node *np = wsp->ws_tail;
-  
+
   size_t i = start;
 
   if (i >= len)
@@ -2064,7 +2068,7 @@ scan_word (struct wordsplit *wsp, size_t start, int consume_all)
   wsp->ws_endp = i;
   if (wsp->ws_flags & WRDSF_INCREMENTAL)
     return _WRDS_EOF;
-  
+
   if (consume_all)
     {
       if (!np)
@@ -2075,7 +2079,7 @@ scan_word (struct wordsplit *wsp, size_t start, int consume_all)
          np = np->next;
        }
     }
-  
+
   return _WRDS_OK;
 }
 
@@ -2342,7 +2346,7 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start)
   if (wsp->ws_flags & WRDSF_SHOWDBG)
     wsp->ws_debug (_("(%02d) Input:%.*s;"),
                   wsp->ws_lvl, (int) wsp->ws_len, wsp->ws_input);
-  
+
   if ((wsp->ws_flags & WRDSF_NOSPLIT)
       || ((wsp->ws_options & WRDSO_MAXWORDS)
          && wsp->ws_wordi + 1 == wsp->ws_maxwords))
@@ -2438,7 +2442,7 @@ wordsplit_run (const char *command, size_t length, struct wordsplit *wsp,
 }
 
 int
-wordsplit_len (const char *command, size_t length, struct wordsplit *wsp, 
+wordsplit_len (const char *command, size_t length, struct wordsplit *wsp,
                unsigned flags)
 {
   return wordsplit_run (command, length, wsp, flags, 0);
@@ -2559,4 +2563,3 @@ wordsplit_perror (struct wordsplit *wsp)
       wsp->ws_error ("%s", wordsplit_strerror (wsp));
     }
 }
-
index 958085f6d74109e3d97f5dbf2b587a564a93bb1f..e43862527443c535e36b37635a32b9d7cf705b96 100644 (file)
@@ -28,6 +28,7 @@
 #include <fnmatch.h>
 #include <human.h>
 #include <quotearg.h>
+#include <verify.h>
 
 #include "common.h"
 #include <rmt.h>
@@ -1325,8 +1326,8 @@ new_volume (enum access_mode mode)
   if (verify_option)
     verify_volume ();
 
-  assign_string (&volume_label, NULL);
-  assign_string (&continued_file_name, NULL);
+  assign_null (&volume_label);
+  assign_null (&continued_file_name);
   continued_file_size = continued_file_offset = 0;
   current_block = record_start;
 
@@ -1505,7 +1506,7 @@ try_new_volume (void)
       ASSIGN_STRING_N (&volume_label, current_header->header.name);
       set_next_block_after (header);
       header = find_next_block ();
-      if (header->header.typeflag != GNUTYPE_MULTIVOL)
+      if (! (header && header->header.typeflag == GNUTYPE_MULTIVOL))
         break;
       FALLTHROUGH;
     case GNUTYPE_MULTIVOL:
@@ -1688,6 +1689,7 @@ _write_volume_label (const char *str)
     {
       union block *label = find_next_block ();
 
+      assume (label);
       memset (label, 0, BLOCKSIZE);
 
       strcpy (label->header.name, str);
index 5d079569889153fb875b392f3d9a05db0e2b749b..3af332981d458de958daabf0ae79602f430c6b92 100644 (file)
 # define GLOBAL extern
 #endif
 
-#if 7 <= __GNUC__
-# define FALLTHROUGH __attribute__ ((__fallthrough__))
-#else
-# define FALLTHROUGH ((void) 0)
-#endif
-
 #define TAREXIT_SUCCESS PAXEXIT_SUCCESS
 #define TAREXIT_DIFFERS PAXEXIT_DIFFERS
 #define TAREXIT_FAILURE PAXEXIT_FAILURE
 
 \f
 #include "arith.h"
+#include <attribute.h>
 #include <backupfile.h>
 #include <exclude.h>
 #include <full-write.h>
@@ -633,7 +628,10 @@ void skip_member (void);
 #define max(a, b) ((a) < (b) ? (b) : (a))
 
 char const *quote_n_colon (int n, char const *arg);
-void assign_string (char **dest, const char *src);
+void assign_string_or_null (char **dest, const char *src)
+  ATTRIBUTE_NONNULL ((1));
+void assign_string (char **dest, const char *src) ATTRIBUTE_NONNULL ((1, 2));
+void assign_null (char **dest) ATTRIBUTE_NONNULL ((1));
 void assign_string_n (char **string, const char *value, size_t n);
 #define ASSIGN_STRING_N(s,v) assign_string_n (s, v, sizeof (v))
 int unquote_string (char *str);
index 80009a54728a979f10625f0a540005a3fc493e9c..85a6f1b26daea5b93699433d828a20e5f05c1a8d 100644 (file)
@@ -520,7 +520,7 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
   data->change_dir = chdir_current;
   data->cntx_name = NULL;
   if (st)
-    assign_string (&data->cntx_name, st->cntx_name);
+    assign_string_or_null (&data->cntx_name, st->cntx_name);
   if (st && st->acls_a_ptr)
     {
       data->acls_a_ptr = xmemdup (st->acls_a_ptr, st->acls_a_len + 1);
@@ -1329,7 +1329,7 @@ extract_file (char *file_name, int typeflag)
    first. If it doesn't exist, there is no matching entry in the list.
    Otherwise, look for the entry in list which has the matching dev
    and ino numbers.
-   
+
    This approach avoids scanning the singly-linked list in obvious cases
    and does not rely on comparing file names, which may differ for
    various reasons (e.g. relative vs. absolute file names).
@@ -1342,14 +1342,14 @@ find_delayed_link_source (char const *name)
 
   if (!delayed_link_head)
     return NULL;
-  
+
   if (fstatat (chdir_fd, name, &st, AT_SYMLINK_NOFOLLOW))
     {
       if (errno != ENOENT)
        stat_error (name);
       return NULL;
     }
-  
+
   for (dl = delayed_link_head; dl; dl = dl->next)
     {
       if (dl->dev == st.st_dev && dl->ino == st.st_ino)
@@ -1357,7 +1357,7 @@ find_delayed_link_source (char const *name)
     }
   return dl;
 }
-  
+
 /* Create a placeholder file with name FILE_NAME, which will be
    replaced after other extraction is done by a symbolic link if
    IS_SYMLINK is true, and by a hard link otherwise.  Set
@@ -1385,7 +1385,7 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made,
           */
          return 0;
        }
-      
+
       switch (maybe_recoverable (file_name, false, interdir_made))
        {
        case RECOVER_OK:
@@ -1442,7 +1442,7 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made,
       p->sources->next = 0;
       strcpy (p->sources->string, file_name);
       p->cntx_name = NULL;
-      assign_string (&p->cntx_name, current_stat_info.cntx_name);
+      assign_string_or_null (&p->cntx_name, current_stat_info.cntx_name);
       p->acls_a_ptr = NULL;
       p->acls_a_len = 0;
       p->acls_d_ptr = NULL;
@@ -1467,7 +1467,7 @@ extract_link (char *file_name, int typeflag)
   char const *link_name;
   int rc;
   struct delayed_link *dl;
-  
+
   link_name = current_stat_info.link_name;
 
   if (! absolute_names_option && contains_dot_dot (link_name))
@@ -1475,7 +1475,7 @@ extract_link (char *file_name, int typeflag)
   dl = find_delayed_link_source (link_name);
   if (dl)
     return create_placeholder_file (file_name, false, &interdir_made, dl);
-  
+
   do
     {
       struct stat st1, st2;
@@ -1697,7 +1697,7 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
 
     case GNUTYPE_VOLHDR:
       return false;
-      
+
     case GNUTYPE_MULTIVOL:
       ERROR ((0, 0,
              _("%s: Cannot extract -- file is continued from another volume"),
@@ -1753,7 +1753,7 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
        }
     }
   *fun = extractor;
-  
+
   return true;
 }
 
index 6819c4670d0c79ed6da4020d93e04fe2a7e6ad3b..3e6ce78fbc8907b4e7946b8b740fc8333e7cb47b 100644 (file)
@@ -42,11 +42,28 @@ quote_n_colon (int n, char const *arg)
 
 /* Assign STRING to a copy of VALUE if not zero, or to zero.  If
    STRING was nonzero, it is freed first.  */
+void
+assign_string_or_null (char **string, const char *value)
+{
+  if (value)
+    assign_string (string, value);
+  else
+    assign_null (string);
+}
+
 void
 assign_string (char **string, const char *value)
 {
   free (*string);
-  *string = value ? xstrdup (value) : 0;
+  *string = xstrdup (value);
+}
+
+void
+assign_null (char **string)
+{
+  char *old = *string;
+  *string = NULL;
+  free (old);
 }
 
 void
@@ -61,6 +78,8 @@ assign_string_n (char **string, const char *value, size_t n)
       p[l] = 0;
       *string = p;
     }
+  else
+    *string = NULL;
 }
 
 #if 0
@@ -715,7 +734,7 @@ maybe_backup_file (const char *file_name, bool this_is_the_archive)
      possible, real problems are unlikely.  Doing any better would require a
      convention, GNU-wide, for all programs doing backups.  */
 
-  assign_string (&after_backup_name, 0);
+  assign_null (&after_backup_name);
 
   /* Check if we really need to backup the file.  */
 
@@ -758,7 +777,7 @@ maybe_backup_file (const char *file_name, bool this_is_the_archive)
       ERROR ((0, e, _("%s: Cannot rename to %s"),
              quotearg_colon (before_backup_name),
              quote_n (1, after_backup_name)));
-      assign_string (&after_backup_name, 0);
+      assign_null (&after_backup_name);
       return false;
     }
 }
@@ -782,7 +801,7 @@ undo_last_backup (void)
        fprintf (stdlis, _("Renaming %s back to %s\n"),
                 quote_n (0, after_backup_name),
                 quote_n (1, before_backup_name));
-      assign_string (&after_backup_name, 0);
+      assign_null (&after_backup_name);
     }
 }
 
@@ -1041,11 +1060,11 @@ tar_getcdpath (int idx)
     {
       int i;
       int save_cwdi = chdir_current;
-      
+
       for (i = idx; i >= 0; i--)
        if (wd[i].abspath)
          break;
-      
+
       while (++i <= idx)
        {
          chdir_do (i);
@@ -1069,7 +1088,7 @@ tar_getcdpath (int idx)
 
       chdir_do (save_cwdi);
     }
-          
+
   return wd[idx].abspath;
 }
 \f