aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2014-05-16 14:17:56 -0400
committerChet Ramey <chet.ramey@case.edu>2014-05-16 14:17:56 -0400
commit3b34f6e68ce94b15608a49feb62702a71bc18665 (patch)
tree020ae10d4fff704e9dffa666b92acb7e3b4d6e9e
parenteec5e6ee83ff3670706a6b5f097ce83202b31c9e (diff)
downloadandroid_external_bash-3b34f6e68ce94b15608a49feb62702a71bc18665.tar.gz
android_external_bash-3b34f6e68ce94b15608a49feb62702a71bc18665.tar.bz2
android_external_bash-3b34f6e68ce94b15608a49feb62702a71bc18665.zip
Bash-4.3 patch 14
-rw-r--r--patchlevel.h2
-rw-r--r--subst.c32
2 files changed, 33 insertions, 1 deletions
diff --git a/patchlevel.h b/patchlevel.h
index 72064c5..20a8267 100644
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 13
+#define PATCHLEVEL 14
#endif /* _PATCHLEVEL_H_ */
diff --git a/subst.c b/subst.c
index e131f4c..f94d129 100644
--- a/subst.c
+++ b/subst.c
@@ -3248,8 +3248,10 @@ cond_expand_word (w, special)
if (w->word == 0 || w->word[0] == '\0')
return ((char *)NULL);
+ expand_no_split_dollar_star = 1;
w->flags |= W_NOSPLIT2;
l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
+ expand_no_split_dollar_star = 0;
if (l)
{
if (special == 0) /* LHS */
@@ -7847,6 +7849,10 @@ param_expand (string, sindex, quoted, expanded_something,
We also want to make sure that splitting is done no matter what --
according to POSIX.2, this expands to a list of the positional
parameters no matter what IFS is set to. */
+ /* XXX - what to do when in a context where word splitting is not
+ performed? Even when IFS is not the default, posix seems to imply
+ that we behave like unquoted $* ? Maybe we should use PF_NOSPLIT2
+ here. */
temp = string_list_dollar_at (list, (pflags & PF_ASSIGNRHS) ? (quoted|Q_DOUBLE_QUOTES) : quoted);
tflag |= W_DOLLARAT;
@@ -8816,6 +8822,7 @@ finished_with_string:
else
{
char *ifs_chars;
+ char *tstring;
ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
@@ -8830,11 +8837,36 @@ finished_with_string:
regardless of what else has happened to IFS since the expansion. */
if (split_on_spaces)
list = list_string (istring, " ", 1); /* XXX quoted == 1? */
+ /* If we have $@ (has_dollar_at != 0) and we are in a context where we
+ don't want to split the result (W_NOSPLIT2), and we are not quoted,
+ we have already separated the arguments with the first character of
+ $IFS. In this case, we want to return a list with a single word
+ with the separator possibly replaced with a space (it's what other
+ shells seem to do).
+ quoted_dollar_at is internal to this function and is set if we are
+ passed an argument that is unquoted (quoted == 0) but we encounter a
+ double-quoted $@ while expanding it. */
+ else if (has_dollar_at && quoted_dollar_at == 0 && ifs_chars && quoted == 0 && (word->flags & W_NOSPLIT2))
+ {
+ /* Only split and rejoin if we have to */
+ if (*ifs_chars && *ifs_chars != ' ')
+ {
+ list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
+ tstring = string_list (list);
+ }
+ else
+ tstring = istring;
+ tword = make_bare_word (tstring);
+ if (tstring != istring)
+ free (tstring);
+ goto set_word_flags;
+ }
else if (has_dollar_at && ifs_chars)
list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
else
{
tword = make_bare_word (istring);
+set_word_flags:
if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
tword->flags |= W_QUOTED;
if (word->flags & W_ASSIGNMENT)