123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- BASH PATCH REPORT
- =================
- Bash-Release: 3.2
- Patch-ID: bash32-014
- Bug-Reported-by: Brett Stahlman <brettstahlman@comcast.net>
- Bug-Reference-ID: <000701c72d29$a227e0e0$5ec7cf47@computerroom>
- Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2006-12/msg00065.html
- Bug-Description:
- Bash mishandles word splitting under certain circumstances when IFS is
- null (IFS=). Constructs affected include ${param/pat/sub} and others
- when expanding arrays (array[@]).
- Patch:
- *** ../bash-3.2-patched/array.c Wed Jun 1 16:39:22 2005
- --- bash-3.2/array.c Mon Jan 15 22:58:00 2007
- ***************
- *** 121,125 ****
- }
-
- - #ifdef INCLUDE_UNUSED
- /*
- * Make and return a new array composed of the elements in array A from
- --- 121,124 ----
- ***************
- *** 142,146 ****
- n = array_create_element (element_index(p), element_value(p));
- ADD_BEFORE(a->head, n);
- ! mi = element_index(ae);
- }
- a->num_elements = i;
- --- 141,145 ----
- n = array_create_element (element_index(p), element_value(p));
- ADD_BEFORE(a->head, n);
- ! mi = element_index(n);
- }
- a->num_elements = i;
- ***************
- *** 148,152 ****
- return a;
- }
- - #endif
-
- /*
- --- 147,150 ----
- ***************
- *** 301,304 ****
- --- 299,319 ----
- }
-
- + ARRAY *
- + array_quote_escapes(array)
- + ARRAY *array;
- + {
- + ARRAY_ELEMENT *a;
- + char *t;
- +
- + if (array == 0 || array_head(array) == 0 || array_empty(array))
- + return (ARRAY *)NULL;
- + for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
- + t = quote_escapes (a->value);
- + FREE(a->value);
- + a->value = t;
- + }
- + return array;
- + }
- +
- /*
- * Return a string whose elements are the members of array A beginning at
- ***************
- *** 312,318 ****
- int starsub, quoted;
- {
- ARRAY_ELEMENT *h, *p;
- arrayind_t i;
- ! char *ifs, sep[2];
-
- p = a ? array_head (a) : 0;
- --- 327,334 ----
- int starsub, quoted;
- {
- + ARRAY *a2;
- ARRAY_ELEMENT *h, *p;
- arrayind_t i;
- ! char *ifs, sep[2], *t;
-
- p = a ? array_head (a) : 0;
- ***************
- *** 337,340 ****
- --- 353,363 ----
- ;
-
- + a2 = array_slice(a, h, p);
- +
- + if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
- + array_quote(a2);
- + else
- + array_quote_escapes(a2);
- +
- if (starsub && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) {
- ifs = getifs();
- ***************
- *** 344,348 ****
- sep[1] = '\0';
-
- ! return (array_to_string_internal (h, p, sep, quoted));
- }
-
- --- 367,374 ----
- sep[1] = '\0';
-
- ! t = array_to_string (a2, sep, 0);
- ! array_dispose(a2);
- !
- ! return t;
- }
-
- ***************
- *** 368,372 ****
-
- if (mflags & MATCH_QUOTED)
- ! array_quote (a2);
- if (mflags & MATCH_STARSUB) {
- ifs = getifs();
- --- 394,400 ----
-
- if (mflags & MATCH_QUOTED)
- ! array_quote(a2);
- ! else
- ! array_quote_escapes(a2);
- if (mflags & MATCH_STARSUB) {
- ifs = getifs();
- *** ../bash-3.2-patched/array.h Sun Jun 1 15:50:30 2003
- --- bash-3.2/array.h Mon Jan 15 22:35:35 2007
- ***************
- *** 56,59 ****
- --- 56,60 ----
- extern int array_shift_element __P((ARRAY *, char *));
- extern ARRAY *array_quote __P((ARRAY *));
- + extern ARRAY *array_quote_escapes __P((ARRAY *));
-
- extern char *array_subrange __P((ARRAY *, arrayind_t, arrayind_t, int, int));
- *** ../bash-3.2-patched/subst.c Fri Mar 2 16:20:50 2007
- --- bash-3.2/subst.c Tue Mar 6 11:40:55 2007
- ***************
- *** 1888,1892 ****
- --- 1889,1899 ----
- #endif
-
- + /* XXX -- why call quote_list if ifs == 0? we can get away without doing
- + it now that quote_escapes quotes spaces */
- + #if 0
- tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
- + #else
- + tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
- + #endif
- ? quote_list (list)
- : list_quote_escapes (list);
- ***************
- *** 2922,2926 ****
- /* Quote escape characters in string s, but no other characters. This is
- used to protect CTLESC and CTLNUL in variable values from the rest of
- ! the word expansion process after the variable is expanded. */
- char *
- quote_escapes (string)
- --- 2935,2944 ----
- /* Quote escape characters in string s, but no other characters. This is
- used to protect CTLESC and CTLNUL in variable values from the rest of
- ! the word expansion process after the variable is expanded. If IFS is
- ! null, we quote spaces as well, just in case we split on spaces later
- ! (in the case of unquoted $@, we will eventually attempt to split the
- ! entire word on spaces). Corresponding code exists in dequote_escapes.
- ! Even if we don't end up splitting on spaces, quoting spaces is not a
- ! problem. */
- char *
- quote_escapes (string)
- ***************
- *** 2930,2933 ****
- --- 2948,2952 ----
- size_t slen;
- char *result, *send;
- + int quote_spaces;
- DECLARE_MBSTATE;
-
- ***************
- *** 2935,2938 ****
- --- 2954,2958 ----
- send = string + slen;
-
- + quote_spaces = (ifs_value && *ifs_value == 0);
- t = result = (char *)xmalloc ((slen * 2) + 1);
- s = string;
- ***************
- *** 2940,2944 ****
- while (*s)
- {
- ! if (*s == CTLESC || *s == CTLNUL)
- *t++ = CTLESC;
- COPY_CHAR_P (t, s, send);
- --- 2960,2964 ----
- while (*s)
- {
- ! if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' '))
- *t++ = CTLESC;
- COPY_CHAR_P (t, s, send);
- ***************
- *** 2982,2985 ****
- --- 3002,3006 ----
- size_t slen;
- char *result, *send;
- + int quote_spaces;
- DECLARE_MBSTATE;
-
- ***************
- *** 2996,3002 ****
- return (strcpy (result, s));
-
- while (*s)
- {
- ! if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
- {
- s++;
- --- 3017,3024 ----
- return (strcpy (result, s));
-
- + quote_spaces = (ifs_value && *ifs_value == 0);
- while (*s)
- {
- ! if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
- {
- s++;
- ***************
- *** 4462,4466 ****
- RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
-
- ! if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
- istring[istring_index++] = CTLESC;
-
- --- 4498,4510 ----
- RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
-
- ! /* This is essentially quote_string inline */
- ! if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
- ! istring[istring_index++] = CTLESC;
- ! /* Escape CTLESC and CTLNUL in the output to protect those characters
- ! from the rest of the word expansions (word splitting and globbing.)
- ! This is essentially quote_escapes inline. */
- ! else if (c == CTLESC)
- ! istring[istring_index++] = CTLESC;
- ! else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0)))
- istring[istring_index++] = CTLESC;
-
- ***************
- *** 5552,5555 ****
- --- 5610,5616 ----
- rely on array_subrange to understand how to deal with them). */
- tt = array_subrange (array_cell (v), e1, e2, starsub, quoted);
- + #if 0
- + /* array_subrange now calls array_quote_escapes as appropriate, so the
- + caller no longer needs to. */
- if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
- {
- ***************
- *** 5558,5561 ****
- --- 5619,5623 ----
- }
- else
- + #endif
- temp = tt;
- break;
- ***************
- *** 5808,5811 ****
- --- 5870,5876 ----
- case VT_ARRAYVAR:
- temp = array_patsub (array_cell (v), p, rep, mflags);
- + #if 0
- + /* Don't need to do this anymore; array_patsub calls array_quote_escapes
- + as appropriate before adding the space separators. */
- if (temp && (mflags & MATCH_QUOTED) == 0)
- {
- ***************
- *** 5814,5817 ****
- --- 5879,5883 ----
- temp = tt;
- }
- + #endif
- break;
- #endif
- *** ../bash-3.2/patchlevel.h Thu Apr 13 08:31:04 2006
- --- bash-3.2/patchlevel.h Mon Oct 16 14:22:54 2006
- ***************
- *** 26,30 ****
- looks for to find the patch level (for the sccs version string). */
-
- ! #define PATCHLEVEL 13
-
- #endif /* _PATCHLEVEL_H_ */
- --- 26,30 ----
- looks for to find the patch level (for the sccs version string). */
-
- ! #define PATCHLEVEL 14
-
- #endif /* _PATCHLEVEL_H_ */
|