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.
This commit is contained in:
Paul Eggert
2021-02-27 16:41:12 -08:00
parent fa6d317bc7
commit 8378991cba
7 changed files with 124 additions and 100 deletions

View 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])

View File

@@ -23,6 +23,7 @@ areadlinkat-with-size
argmatch
argp
argp-version-etc
attribute
backupfile
closeout
configmake

View 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));
}
}

View 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);

View File

@@ -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);

View 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;
}

View 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;
}