Fix core dump on Solaris 10 when "." isn't readable.
Reported by Peter Kruse in <http://lists.gnu.org/archive/html/bug-tar/2013-10/msg00017.html>. This doesn't fix all the Solaris 10 test failures, just the core dump. * src/common.h, src/misc.c (tar_getcdpath): Now static. * src/misc.c (normalize_filename): Report a fatal error if cdpath is null, since we don't know the absolute name of the working directory in that case. FIXME: there should be no need to know absolute file names. (chdir_arg): Simplify wd allocation. Don't assume that xgetcwd returns non-null.
This commit is contained in:
@@ -609,7 +609,6 @@ char *namebuf_name (namebuf_t buf, const char *name);
|
||||
void namebuf_add_dir (namebuf_t buf, const char *name);
|
||||
char *namebuf_finish (namebuf_t buf);
|
||||
|
||||
const char *tar_getcdpath (int);
|
||||
const char *tar_dirname (void);
|
||||
|
||||
/* Represent N using a signed integer I such that (uintmax_t) I == N.
|
||||
|
||||
51
src/misc.c
51
src/misc.c
@@ -29,6 +29,8 @@
|
||||
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
|
||||
#endif
|
||||
|
||||
static const char *tar_getcdpath (int);
|
||||
|
||||
|
||||
/* Handling strings. */
|
||||
|
||||
@@ -230,7 +232,7 @@ zap_slashes (char *name)
|
||||
|
||||
/* Normalize FILE_NAME by removing redundant slashes and "."
|
||||
components, including redundant trailing slashes.
|
||||
Leave ".." alone, as it may be significant in the presence
|
||||
Leave ".." alone, as it may be significant in the presence
|
||||
of symlinks and on platforms where "/.." != "/".
|
||||
|
||||
Destructive version: modifies its argument. */
|
||||
@@ -290,7 +292,9 @@ normalize_filename (int cdidx, const char *name)
|
||||
const char *cdpath = tar_getcdpath (cdidx);
|
||||
size_t copylen;
|
||||
bool need_separator;
|
||||
|
||||
|
||||
if (!cdpath)
|
||||
call_arg_fatal ("getcwd", ".");
|
||||
copylen = strlen (cdpath);
|
||||
need_separator = ! (DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||
&& copylen == 2 && ISSLASH (cdpath[1]));
|
||||
@@ -834,10 +838,11 @@ struct wd
|
||||
{
|
||||
/* The directory's name. */
|
||||
char const *name;
|
||||
/* "absolute" path representing this directory; in the contrast to
|
||||
/* "Absolute" path representing this directory; in the contrast to
|
||||
the real absolute pathname, it can contain /../ components (see
|
||||
normalize_filename_x for the reason of it). */
|
||||
char *abspath;
|
||||
normalize_filename_x for the reason of it). It is NULL if the
|
||||
absolute path could not be determined. */
|
||||
char *abspath;
|
||||
/* If nonzero, the file descriptor of the directory, or AT_FDCWD if
|
||||
the working directory. If zero, the directory needs to be opened
|
||||
to be used. */
|
||||
@@ -879,15 +884,13 @@ chdir_count (void)
|
||||
int
|
||||
chdir_arg (char const *dir)
|
||||
{
|
||||
char *absdir;
|
||||
|
||||
if (wd_count == wd_alloc)
|
||||
{
|
||||
if (wd_alloc == 0)
|
||||
{
|
||||
wd_alloc = 2;
|
||||
wd = xmalloc (sizeof *wd * wd_alloc);
|
||||
}
|
||||
else
|
||||
wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
|
||||
wd_alloc = 2;
|
||||
wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
|
||||
|
||||
if (! wd_count)
|
||||
{
|
||||
@@ -909,18 +912,22 @@ chdir_arg (char const *dir)
|
||||
return wd_count - 1;
|
||||
}
|
||||
|
||||
wd[wd_count].name = dir;
|
||||
/* if the given name is an absolute path, then use that path
|
||||
to represent this working directory; otherwise, construct
|
||||
a path based on the previous -C option's absolute path */
|
||||
if (IS_ABSOLUTE_FILE_NAME (wd[wd_count].name))
|
||||
wd[wd_count].abspath = xstrdup (wd[wd_count].name);
|
||||
else
|
||||
|
||||
/* If the given name is absolute, use it to represent this directory;
|
||||
otherwise, construct a name based on the previous -C option. */
|
||||
if (IS_ABSOLUTE_FILE_NAME (dir))
|
||||
absdir = xstrdup (dir);
|
||||
else if (wd[wd_count - 1].abspath)
|
||||
{
|
||||
namebuf_t nbuf = namebuf_create (wd[wd_count - 1].abspath);
|
||||
namebuf_add_dir (nbuf, wd[wd_count].name);
|
||||
wd[wd_count].abspath = namebuf_finish (nbuf);
|
||||
namebuf_add_dir (nbuf, dir);
|
||||
absdir = namebuf_finish (nbuf);
|
||||
}
|
||||
else
|
||||
absdir = 0;
|
||||
|
||||
wd[wd_count].name = dir;
|
||||
wd[wd_count].abspath = absdir;
|
||||
wd[wd_count].fd = 0;
|
||||
return wd_count++;
|
||||
}
|
||||
@@ -1007,7 +1014,7 @@ tar_dirname (void)
|
||||
chdir_args() has never been called, so we simply return the
|
||||
process's actual cwd. (Note that in this case IDX is ignored,
|
||||
since it should always be 0.) */
|
||||
const char *
|
||||
static const char *
|
||||
tar_getcdpath (int idx)
|
||||
{
|
||||
if (!wd)
|
||||
@@ -1206,7 +1213,7 @@ char *
|
||||
namebuf_finish (namebuf_t buf)
|
||||
{
|
||||
char *res = buf->buffer;
|
||||
|
||||
|
||||
if (ISSLASH (buf->buffer[buf->dir_length - 1]))
|
||||
buf->buffer[buf->dir_length] = 0;
|
||||
free (buf);
|
||||
|
||||
Reference in New Issue
Block a user