Better xsparse outname guessing
* scripts/xsparse.c (guess_outname): Use simpler algorithm, that doesn’t mishandle outnames like ‘/foo’.
This commit is contained in:
15
doc/tar.texi
15
doc/tar.texi
@@ -11014,17 +11014,12 @@ will deduce the name for the resulting expanded file using the
|
||||
following algorithm:
|
||||
|
||||
@enumerate 1
|
||||
@item If @file{cond-file} does not contain any directories,
|
||||
@file{../cond-file} will be used;
|
||||
@item
|
||||
If @file{cond-file} has the form @file{@var{dir}/@var{name}},
|
||||
the output file name will be @file{@var{dir}/../@var{name}}.
|
||||
|
||||
@item If @file{cond-file} has the form
|
||||
@file{@var{dir}/@var{t}/@var{name}}, where both @var{t} and @var{name}
|
||||
are simple names, with no @samp{/} characters in them, the output file
|
||||
name will be @file{@var{dir}/@var{name}}.
|
||||
|
||||
@item Otherwise, if @file{cond-file} has the form
|
||||
@file{@var{dir}/@var{name}}, the output file name will be
|
||||
@file{@var{name}}.
|
||||
@item
|
||||
Otherwise, the output file name will be @file{../cond-file}.
|
||||
@end enumerate
|
||||
|
||||
In the unlikely case when this algorithm does not suit your needs,
|
||||
|
||||
@@ -336,43 +336,15 @@ usage (int code)
|
||||
static void
|
||||
guess_outname (char *name)
|
||||
{
|
||||
char *p;
|
||||
char *s;
|
||||
|
||||
if (name[0] == '.' && name[1] == '/')
|
||||
name += 2;
|
||||
|
||||
p = name + strlen (name) - 1;
|
||||
s = NULL;
|
||||
|
||||
for (; p > name && *p != '/'; p--)
|
||||
;
|
||||
if (*p == '/')
|
||||
s = p + 1;
|
||||
if (p != name)
|
||||
{
|
||||
for (p--; p > name && *p != '/'; p--)
|
||||
;
|
||||
}
|
||||
|
||||
if (*p != '/')
|
||||
{
|
||||
if (s)
|
||||
outname = s;
|
||||
else
|
||||
{
|
||||
outname = emalloc (4 + strlen (name));
|
||||
strcpy (outname, "../");
|
||||
strcpy (outname + 3, name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t len = p - name + 1;
|
||||
outname = emalloc (len + strlen (s) + 1);
|
||||
memcpy (outname, name, len);
|
||||
strcpy (outname + len, s);
|
||||
}
|
||||
char *base = strrchr (name, '/');
|
||||
base = base ? base + 1 : name;
|
||||
size_t dirlen = base - name, baselen = strlen (base);
|
||||
static char const parentdir[] = "../";
|
||||
int parentdirlen = sizeof parentdir - 1;
|
||||
outname = emalloc (dirlen + parentdirlen + baselen + 1);
|
||||
memcpy (outname, name, dirlen);
|
||||
memcpy (outname + dirlen, parentdir, parentdirlen);
|
||||
memcpy (outname + dirlen + parentdirlen, base, baselen + 1);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user