Bash-4.4 patch 12

This commit is contained in:
Chet Ramey 2017-01-27 11:25:44 -05:00
commit bc007799f0
2 changed files with 21 additions and 13 deletions

View file

@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */ looks for to find the patch level (for the sccs version string). */
#define PATCHLEVEL 11 #define PATCHLEVEL 12
#endif /* _PATCHLEVEL_H_ */ #endif /* _PATCHLEVEL_H_ */

32
subst.c
View file

@ -2825,11 +2825,15 @@ list_string (string, separators, quoted)
/* Parse a single word from STRING, using SEPARATORS to separate fields. /* 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 ENDPTR is set to the first character after the word. This is used by
the `read' builtin. This is never called with SEPARATORS != $IFS; the `read' builtin.
it should be simplified.
This is never called with SEPARATORS != $IFS, and takes advantage of that.
XXX - this function is very similar to list_string; they should be XXX - this function is very similar to list_string; they should be
combined - XXX */ combined - XXX */
#define islocalsep(c) (local_cmap[(unsigned char)(c)] != 0)
char * char *
get_word_from_string (stringp, separators, endptr) get_word_from_string (stringp, separators, endptr)
char **stringp, *separators, **endptr; char **stringp, *separators, **endptr;
@ -2837,6 +2841,7 @@ get_word_from_string (stringp, separators, endptr)
register char *s; register char *s;
char *current_word; char *current_word;
int sindex, sh_style_split, whitesep, xflags; int sindex, sh_style_split, whitesep, xflags;
unsigned char local_cmap[UCHAR_MAX+1]; /* really only need single-byte chars here */
size_t slen; size_t slen;
if (!stringp || !*stringp || !**stringp) if (!stringp || !*stringp || !**stringp)
@ -2846,20 +2851,23 @@ get_word_from_string (stringp, separators, endptr)
separators[1] == '\t' && separators[1] == '\t' &&
separators[2] == '\n' && separators[2] == '\n' &&
separators[3] == '\0'; separators[3] == '\0';
for (xflags = 0, s = ifs_value; s && *s; s++) memset (local_cmap, '\0', sizeof (local_cmap));
for (xflags = 0, s = separators; s && *s; s++)
{ {
if (*s == CTLESC) xflags |= SX_NOCTLESC; if (*s == CTLESC) xflags |= SX_NOCTLESC;
if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL; if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
local_cmap[(unsigned char)*s] = 1; /* local charmap of separators */
} }
s = *stringp; s = *stringp;
slen = 0; slen = 0;
/* Remove sequences of whitespace at the beginning of STRING, as /* Remove sequences of whitespace at the beginning of STRING, as
long as those characters appear in IFS. */ long as those characters appear in SEPARATORS. This happens if
if (sh_style_split || !separators || !*separators) SEPARATORS == $' \t\n' or if IFS is unset. */
if (sh_style_split || separators == 0)
{ {
for (; *s && spctabnl (*s) && isifs (*s); s++); for (; *s && spctabnl (*s) && islocalsep (*s); s++);
/* If the string is nothing but whitespace, update it and return. */ /* If the string is nothing but whitespace, update it and return. */
if (!*s) if (!*s)
@ -2878,9 +2886,9 @@ get_word_from_string (stringp, separators, endptr)
This obeys the field splitting rules in Posix.2. */ This obeys the field splitting rules in Posix.2. */
sindex = 0; sindex = 0;
/* Don't need string length in ADVANCE_CHAR or string_extract_verbatim /* Don't need string length in ADVANCE_CHAR unless multibyte chars are
unless multibyte chars are possible. */ possible, but need it in string_extract_verbatim for bounds checking */
slen = (MB_CUR_MAX > 1) ? STRLEN (s) : 1; slen = STRLEN (s);
current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags); current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
/* Set ENDPTR to the first character after the end of the word. */ /* Set ENDPTR to the first character after the end of the word. */
@ -2899,19 +2907,19 @@ get_word_from_string (stringp, separators, endptr)
/* Now skip sequences of space, tab, or newline characters if they are /* Now skip sequences of space, tab, or newline characters if they are
in the list of separators. */ in the list of separators. */
while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex])) while (s[sindex] && spctabnl (s[sindex]) && islocalsep (s[sindex]))
sindex++; sindex++;
/* If the first separator was IFS whitespace and the current character is /* If the first separator was IFS whitespace and the current character is
a non-whitespace IFS character, it should be part of the current field a non-whitespace IFS character, it should be part of the current field
delimiter, not a separate delimiter that would result in an empty field. delimiter, not a separate delimiter that would result in an empty field.
Look at POSIX.2, 3.6.5, (3)(b). */ Look at POSIX.2, 3.6.5, (3)(b). */
if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex])) if (s[sindex] && whitesep && islocalsep (s[sindex]) && !spctabnl (s[sindex]))
{ {
sindex++; sindex++;
/* An IFS character that is not IFS white space, along with any adjacent /* An IFS character that is not IFS white space, along with any adjacent
IFS white space, shall delimit a field. */ IFS white space, shall delimit a field. */
while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex])) while (s[sindex] && spctabnl (s[sindex]) && islocalsep(s[sindex]))
sindex++; sindex++;
} }