diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | dep.h | 7 | ||||
-rw-r--r-- | read.c | 59 |
3 files changed, 54 insertions, 18 deletions
@@ -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. @@ -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)) @@ -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; - - /* If we have just "lib(", part of something like "lib( a b)", - go to the next item. */ - if (! nlen) - continue; + /* 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; + + /* 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; |