summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2021-02-27 16:41:12 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2021-02-27 16:42:49 -0800
commit8378991cba68d4adf74f3cec3d6ab07ed2e325d0 (patch)
treef55d9c806e98125918c405256244a7446bf3155a
parentfa6d317bc73404c24eab4d045a962126438f403b (diff)
downloadtar-8378991cba68d4adf74f3cec3d6ab07ed2e325d0.tar.gz
maint: port to Fedora 33
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.
-rw-r--r--configure.ac7
-rw-r--r--gnulib.modules1
-rw-r--r--lib/wordsplit.c141
-rw-r--r--src/buffer.c8
-rw-r--r--src/common.h12
-rw-r--r--src/extract.c22
-rw-r--r--src/misc.c33
7 files changed, 124 insertions, 100 deletions
diff --git a/configure.ac b/configure.ac
index 8beba5d1..f9d6c8b3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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])
diff --git a/gnulib.modules b/gnulib.modules
index 68936094..c2900003 100644
--- a/gnulib.modules
+++ b/gnulib.modules
@@ -23,6 +23,7 @@ areadlinkat-with-size
argmatch
argp
argp-version-etc
+attribute
backupfile
closeout
configmake
diff --git a/lib/wordsplit.c b/lib/wordsplit.c
index 661a4f8b..28390c5b 100644
--- a/lib/wordsplit.c
+++ b/lib/wordsplit.c
@@ -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));
}
}
-
diff --git a/src/buffer.c b/src/buffer.c
index 958085f6..e4386252 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -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);
diff --git a/src/common.h b/src/common.h
index 5d079569..3af33298 100644
--- a/src/common.h
+++ b/src/common.h
@@ -43,18 +43,13 @@
# 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
#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);
diff --git a/src/extract.c b/src/extract.c
index 80009a54..85a6f1b2 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -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;
}
diff --git a/src/misc.c b/src/misc.c
index 6819c467..3e6ce78f 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -43,10 +43,27 @@ 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;
}