Do not consider filenames that contain parens but don't END in a paren,

to be an archive group.  Fixes Savannah bug #28525.
This commit is contained in:
Paul Smith 2010-07-03 16:45:45 +00:00
parent 97f106fa10
commit fc644b4c45
3 changed files with 53 additions and 17 deletions

View file

@ -1,3 +1,9 @@
2010-07-03 Paul Smith <psmith@gnu.org>
* read.c (parse_file_seq): All archive groups must end with ')' as
the LAST character in a word. If there is no word ending in ')'
then it's not an archive group. Fixes Savannah bug #28525.
2010-07-01 Paul Smith <psmith@gnu.org>
* main.c (main): Append optional features using separate calls.

7
dep.h
View file

@ -58,9 +58,10 @@ struct nameseq
#define PARSEFS_NONE (0x0000)
#define PARSEFS_NOSTRIP (0x0001)
#define PARSEFS_NOGLOB (0x0002)
#define PARSEFS_EXISTS (0x0004)
#define PARSEFS_NOCACHE (0x0008)
#define PARSEFS_NOAR (0x0002)
#define PARSEFS_NOGLOB (0x0004)
#define PARSEFS_EXISTS (0x0008)
#define PARSEFS_NOCACHE (0x0010)
#define PARSE_FILE_SEQ(_s,_t,_c,_p,_f) \
(_t *)parse_file_seq ((_s),sizeof (_t),(_c),(_p),(_f))

57
read.c
View file

@ -846,9 +846,10 @@ eval (struct ebuffer *ebuf, int set_default)
continue;
}
/* Parse the list of file names. */
/* Parse the list of file names. Don't expand archive references! */
p2 = p;
files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, 0);
files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL,
PARSEFS_NOAR);
free (p);
/* Save the state of conditionals and start
@ -2833,6 +2834,7 @@ tilde_expand (const char *name)
FLAGS allows one or more of the following bitflags to be set:
PARSEFS_NOSTRIP - Do no strip './'s off the beginning
PARSEFS_NOAR - Do not check filenames for archive references
PARSEFS_NOGLOB - Do not expand globbing characters
PARSEFS_EXISTS - Only return globbed files that actually exist
(cannot also set NOGLOB)
@ -2998,28 +3000,55 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
#ifndef NO_ARCHIVES
/* If this is the start of an archive group that isn't complete, set up
to add the archive prefix for future files.
to add the archive prefix for future files. A file list like:
"libf.a(x.o y.o z.o)" needs to be expanded as:
"libf.a(x.o) libf.a(y.o) libf.a(z.o)"
TP == TMP means we're not already in an archive group. Ignore
something starting with `(', as that cannot actually be an
archive-member reference (and treating it as such results in an empty
file name, which causes much lossage). Also if it ends in ")" then
it's a complete reference so we don't need to treat it specially. */
it's a complete reference so we don't need to treat it specially.
if (tp == tmpbuf && tp[0] != '(' && tp[nlen-1] != ')')
Finally, note that archive groups must end with ')' as the last
character, so ensure there's some word ending like that before
considering this an archive group. */
if (! (flags & PARSEFS_NOAR)
&& tp == tmpbuf && tp[0] != '(' && tp[nlen-1] != ')')
{
char *n = strchr (tp, '(');
if (n)
{
/* This is the first element in an open archive group. It looks
like "lib(mem". Remember the close paren. */
nlen -= (n + 1) - tp;
tp = n + 1;
/* This looks like the first element in an open archive group.
A valid group MUST have ')' as the last character. */
const char *e = p + nlen;
do
{
e = next_token (e);
/* Find the end of this word. We don't want to unquote and
we don't care about quoting since we're looking for the
last char in the word. */
while (*e != '\0' && *e != stopchar && *e != VMS_COMMA
&& ! isblank ((unsigned char) *e))
++e;
if (e[-1] == ')')
{
/* Found the end, so this is the first element in an
open archive group. It looks like "lib(mem".
Reset TP past the open paren. */
nlen -= (n + 1) - tp;
tp = n + 1;
/* If we have just "lib(", part of something like "lib( a b)",
go to the next item. */
if (! nlen)
continue;
/* If we have just "lib(", part of something like
"lib( a b)", go to the next item. */
if (! nlen)
continue;
/* We can stop looking now. */
break;
}
}
while (*e != '\0');
}
}
@ -3069,7 +3098,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
/* If NAME is an archive member reference replace it with the archive
file name, and save the member name in MEMNAME. We will glob on the
archive name and then reattach MEMNAME later. */
if (ar_name (name))
if (! (flags & PARSEFS_NOAR) && ar_name (name))
{
ar_parse_name (name, &arname, &memname);
name = arname;