Bash-4.2 patch 40
[platform/upstream/bash.git] / subst.c
diff --git a/subst.c b/subst.c
index c9a0678..937c71d 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -4166,7 +4166,7 @@ match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
   simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'[');
 #if defined (EXTENDED_GLOB)
   if (extended_glob)
-    simple |= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
+    simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
 #endif
 
   /* If the pattern doesn't match anywhere in the string, go ahead and
@@ -5809,6 +5809,16 @@ parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
         is the only expansion that creates more than one word. */
       if (qdollaratp && ((hasdol && quoted) || l->next))
        *qdollaratp = 1;
+      /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
+        a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
+        flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
+        expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
+        (which is more paranoia than anything else), we need to return the
+        quoted null string and set the flags to indicate it. */
+      if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL(temp) && QUOTED_NULL(l->word->word) && (l->word->flags & W_HASQUOTEDNULL))
+       {
+         w->flags |= W_HASQUOTEDNULL;
+       }
       dispose_words (l);
     }
   else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
@@ -7912,7 +7922,7 @@ expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_somethin
 
   /* State flags */
   int had_quoted_null;
-  int has_dollar_at;
+  int has_dollar_at, temp_has_dollar_at;
   int tflag;
   int pflags;                  /* flags passed to param_expand */
 
@@ -8117,13 +8127,14 @@ add_string:
          if (expanded_something)
            *expanded_something = 1;
 
-         has_dollar_at = 0;
+         temp_has_dollar_at = 0;
          pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0;
          if (word->flags & W_NOSPLIT2)
            pflags |= PF_NOSPLIT2;
          tword = param_expand (string, &sindex, quoted, expanded_something,
-                              &has_dollar_at, &quoted_dollar_at,
+                              &temp_has_dollar_at, &quoted_dollar_at,
                               &had_quoted_null, pflags);
+         has_dollar_at += temp_has_dollar_at;
 
          if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
            {
@@ -8141,6 +8152,14 @@ add_string:
          temp = tword->word;
          dispose_word_desc (tword);
 
+         /* Kill quoted nulls; we will add them back at the end of
+            expand_word_internal if nothing else in the string */
+         if (had_quoted_null && temp && QUOTED_NULL (temp))
+           {
+             FREE (temp);
+             temp = (char *)NULL;
+           }
+
          goto add_string;
          break;
 
@@ -8256,9 +8275,10 @@ add_twochars:
 
              temp = (char *)NULL;
 
-             has_dollar_at = 0;
+             temp_has_dollar_at = 0;   /* XXX */
              /* Need to get W_HASQUOTEDNULL flag through this function. */
-             list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
+             list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &temp_has_dollar_at, (int *)NULL);
+             has_dollar_at += temp_has_dollar_at;
 
              if (list == &expand_word_error || list == &expand_word_fatal)
                {
@@ -8545,7 +8565,7 @@ finished_with_string:
        tword->flags |= W_NOEXPAND;     /* XXX */
       if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
        tword->flags |= W_QUOTED;
-      if (had_quoted_null)
+      if (had_quoted_null && QUOTED_NULL (istring))
        tword->flags |= W_HASQUOTEDNULL;
       list = make_word_list (tword, (WORD_LIST *)NULL);
     }
@@ -8576,7 +8596,7 @@ finished_with_string:
            tword->flags |= W_NOGLOB;
          if (word->flags & W_NOEXPAND)
            tword->flags |= W_NOEXPAND;
-         if (had_quoted_null)
+         if (had_quoted_null && QUOTED_NULL (istring))
            tword->flags |= W_HASQUOTEDNULL;    /* XXX */
          list = make_word_list (tword, (WORD_LIST *)NULL);
        }