Re: bug in 4.4?

2017-01-27 Thread Chet Ramey
On 1/26/17 7:53 PM, Grisha Levit wrote:
> This seems to be the following change (from CHANGES)
> 
>> 
> 
> |
> a. Using ${a[@]} or ${a[*]} with an array without any assigned elements
> when the nounset option is enabled no longer throws an unbound variable 
> error.|
> 
> 
> This mirrors the behavior of $@.

http://lists.gnu.org/archive/html/bug-bash/2016-07/msg00031.html

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Bash-4.4 Official Patch 12

2017-01-27 Thread Chet Ramey
 BASH PATCH REPORT
 =

Bash-Release:   4.4
Patch-ID:   bash44-012

Bug-Reported-by:Clark Wang 
Bug-Reference-ID:   

Bug-Reference-URL:  
http://lists.gnu.org/archive/html/bug-bash/2016-11/msg00106.html

Bug-Description:

When -N is used, the input is not supposed to be split using $IFS, but
leading and trailing IFS whitespace was still removed.

Patch (apply with `patch -p0'):

*** ../bash-4.4-patched/subst.c 2017-01-20 14:22:01.0 -0500
--- subst.c 2017-01-25 13:43:22.0 -0500
***
*** 2826,2834 
  /* Parse a single word from STRING, using SEPARATORS to separate fields.
 ENDPTR is set to the first character after the word.  This is used by
!the `read' builtin.  This is never called with SEPARATORS != $IFS;
!it should be simplified.
  
 XXX - this function is very similar to list_string; they should be
 combined - XXX */
  char *
  get_word_from_string (stringp, separators, endptr)
--- 2826,2838 
  /* Parse a single word from STRING, using SEPARATORS to separate fields.
 ENDPTR is set to the first character after the word.  This is used by
!the `read' builtin.
!
!This is never called with SEPARATORS != $IFS, and takes advantage of that.
  
 XXX - this function is very similar to list_string; they should be
 combined - XXX */
+ 
+ #define islocalsep(c) (local_cmap[(unsigned char)(c)] != 0)
+ 
  char *
  get_word_from_string (stringp, separators, endptr)
***
*** 2838,2841 
--- 2842,2846 
char *current_word;
int sindex, sh_style_split, whitesep, xflags;
+   unsigned char local_cmap[UCHAR_MAX+1];  /* really only need single-byte 
chars here */
size_t slen;
  
***
*** 2847,2854 
 separators[2] == '\n' &&
 separators[3] == '\0';
!   for (xflags = 0, s = ifs_value; s && *s; s++)
  {
if (*s == CTLESC) xflags |= SX_NOCTLESC;
if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
  }
  
--- 2852,2861 
 separators[2] == '\n' &&
 separators[3] == '\0';
!   memset (local_cmap, '\0', sizeof (local_cmap));
!   for (xflags = 0, s = separators; s && *s; s++)
  {
if (*s == CTLESC) xflags |= SX_NOCTLESC;
if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
+   local_cmap[(unsigned char)*s] = 1;  /* local charmap of separators 
*/
  }
  
***
*** 2857,2864 
  
/* Remove sequences of whitespace at the beginning of STRING, as
!  long as those characters appear in IFS. */
!   if (sh_style_split || !separators || !*separators)
  {
!   for (; *s && spctabnl (*s) && isifs (*s); s++);
  
/* If the string is nothing but whitespace, update it and return. */
--- 2864,2872 
  
/* Remove sequences of whitespace at the beginning of STRING, as
!  long as those characters appear in SEPARATORS.  This happens if
!  SEPARATORS == $' \t\n' or if IFS is unset. */
!   if (sh_style_split || separators == 0)
  {
!   for (; *s && spctabnl (*s) && islocalsep (*s); s++);
  
/* If the string is nothing but whitespace, update it and return. */
***
*** 2879,2885 
   This obeys the field splitting rules in Posix.2. */
sindex = 0;
!   /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
!  unless multibyte chars are possible. */
!   slen = (MB_CUR_MAX > 1) ? STRLEN (s) : 1;
current_word = string_extract_verbatim (s, slen, &sindex, separators, 
xflags);
  
--- 2887,2893 
   This obeys the field splitting rules in Posix.2. */
sindex = 0;
!   /* Don't need string length in ADVANCE_CHAR unless multibyte chars are
!  possible, but need it in string_extract_verbatim for bounds checking */
!   slen = STRLEN (s);
current_word = string_extract_verbatim (s, slen, &sindex, separators, 
xflags);
  
***
*** 2900,2904 
/* Now skip sequences of space, tab, or newline characters if they are
   in the list of separators. */
!   while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
  sindex++;
  
--- 2908,2912 
/* Now skip sequences of space, tab, or newline characters if they are
   in the list of separators. */
!   while (s[sindex] && spctabnl (s[sindex]) && islocalsep (s[sindex]))
  sindex++;
  
***
*** 2907,2916 
   delimiter, not a separate delimiter that would result in an empty field.
   Look at POSIX.2, 3.6.5, (3)(b). */
!   if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
  {
sindex++;
/* An IFS character that is not IFS white space, along with any adjacent
 IFS white space, shall delimit a field. */
!   while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
sindex++;
  }
--- 2915,2