]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
changes for backslashes in glob patterns and single-quoted strings; brace expansion...
authorChet Ramey <chet.ramey@case.edu>
Tue, 17 Oct 2023 15:09:23 +0000 (11:09 -0400)
committerChet Ramey <chet.ramey@case.edu>
Tue, 17 Oct 2023 15:09:23 +0000 (11:09 -0400)
CWRU/CWRU.chlog
braces.c
builtins/read.def
lib/sh/strtrans.c
parse.y
pathexp.c
subst.c
subst.h

index 773912d18a9ad1ee79c0c10d1b4477e594a47abf..a9f2dfe49a5e5b8c22e1072a2805fa304bba7bf7 100644 (file)
@@ -6861,7 +6861,6 @@ builtins/evalstring.c
 subst.c
        - param_expand: free TEMP1 in code paths that don't do it now
 
-
 bashline.c
        - bash_command_name_stat_hook: if we modify *NAME, free the old value
 
@@ -7825,3 +7824,43 @@ builtins/return.def
          invalid numeric arg from get_exitstat, return immediately and let
          the caller deal with exiting
          All prompted by a report by Martin Schulte <gnu@schrader-schulte.de>
+
+                                  10/13
+                                  -----
+pathexp.c
+       - unquoted_glob_pattern_p: restore some of the special treatment of
+         backslash followed by CTLESC removed on 10/7
+         Report and patch from Grisha Levit <grishalevit@gmail.com>
+
+parse.y
+       - parse_matched_pair: don't add an extra CTLESC after reading \CTLESC,
+         like in other parts of the parser
+
+subst.c
+       - dequote_string: don't drop trailing CTLESC in a string with more
+         than a single character
+         Report and patch from Grisha Levit <grishalevit@gmail.com>
+
+lib/sh/strtrans.c
+       - ansicstr: handle $'\c^A' and $'\c^?' correctly when being expanded
+         by the parser (flags&2). The parser passes these as \c^A^A and
+         \c^A^?, respectively, so we should strip the quoting CTLESC.
+         Report from Grisha Levit <grishalevit@gmail.com>
+
+subst.[ch]
+       - extract_dollar_brace_string: now global so brace expansion can use it
+
+braces.c
+       - brace_gobbler: use extract_dollar_brace_string if we see ${ with
+         the appropriate value of QUOTING, so we don't have to teach brace
+         expansion more shell syntax.
+         Report from Emanuele Torre <torreemanuele6@gmail.com>
+       - brace_gobbler: call the word extraction functions with SX_NOALLOC
+         so we don't have to allocate memory we're just going to free
+
+                                  10/16
+                                  -----
+builtins/read.def
+       - read_builtin: return EX_MISCERROR (2) if there is an error trying
+         to assign to one of the variables. This is what the newest POSIX
+         draft specifies.
index a4476868c17820a3e60968456fabdd139aeb6a30..3d096db75d68a8316eab977669cc32b6598e94fc 100644 (file)
--- a/braces.c
+++ b/braces.c
@@ -619,10 +619,9 @@ brace_gobbler (char *text, size_t tlen, int *indx, int satisfy)
       /* If compiling for the shell, treat ${...} like \{...} */
       if (c == '$' && text[i+1] == '{' && quoted != '\'')              /* } */
        {
-         pass_next = 1;
-         i++;
-         if (quoted == 0)
-           level++;
+         si = i + 2;
+         t = extract_dollar_brace_string (text, &si, 0, SX_NOALLOC);
+         i = si + 1;
          continue;
        }
 #endif
@@ -657,10 +656,8 @@ brace_gobbler (char *text, size_t tlen, int *indx, int satisfy)
        {
 comsub:
          si = i + 2;
-         t = extract_command_subst (text, &si, 0);
-         i = si;
-         free (t);
-         i++;
+         t = extract_command_subst (text, &si, SX_NOALLOC);
+         i = si + 1;
          continue;
        }
 #endif
index 587be28738898b210fbc58102d0e8d298b24367a..0fcc6f4e4d4b36856732ff8cf3fa15cf766e4012 100644 (file)
@@ -500,7 +500,7 @@ read_builtin (WORD_LIST *list)
       read_timeout = shtimer_alloc ();
       read_timeout->flags = SHTIMER_LONGJMP;
 
-#if defined (HAVE_SELECT)
+#if defined (HAVE_SELECT) || defined (HAVE_PSELECT)
       read_timeout->flags |= (edit || posixly_correct) ? SHTIMER_ALARM : SHTIMER_SELECT;
 #else
       read_timeout->flags |= SHTIMER_ALARM;
@@ -966,7 +966,7 @@ assign_vars:
       else
        var = bind_variable ("REPLY", input_string, 0);
       if (var == 0 || readonly_p (var) || noassign_p (var))
-       retval = EXECUTION_FAILURE;
+       retval = EX_MISCERROR;
       else
        VUNSETATTR (var, att_invisible);
 
@@ -1027,7 +1027,7 @@ assign_vars:
       if (var == 0)
        {
          free (orig_input_string);
-         return (EXECUTION_FAILURE);
+         return (EX_MISCERROR);
        }
 
       stupidly_hack_special_variables (varname);
index d3b27f3bff49b09267e768cc44b5524281b88d37..af75dcfa820dec170474c8a4b059687456bab672 100644 (file)
@@ -45,7 +45,7 @@
    that we're translating a string for `echo -e', and therefore should not
    treat a single quote as a character that may be escaped with a backslash.
    If (FLAGS&2) is non-zero, we're expanding for the parser and want to
-   quote CTLESC and CTLNUL with CTLESC.  If (flags&4) is non-zero, we want
+   quote CTLESC and CTLNUL with CTLESC.  If (FLAGS&4) is non-zero, we want
    to remove the backslash before any unrecognized escape sequence. */
 char *
 ansicstr (const char *string, size_t len, int flags, int *sawc, size_t *rlen)
@@ -198,7 +198,9 @@ ansicstr (const char *string, size_t len, int flags, int *sawc, size_t *rlen)
                  s++;
                  if ((flags & 2) && c == '\\' && c == *s)
                    s++;        /* Posix requires $'\c\\' do backslash escaping */
-                 c = TOCTRL(c);
+                 else if ((flags & 2) && c == CTLESC && (*s == CTLESC || *s == CTLNUL))
+                   c = *s++;
+                 c = TOCTRL(c);
                  break;
                }
                /*FALLTHROUGH*/
diff --git a/parse.y b/parse.y
index 3e5b814f23755435345282b19cb79e0a8147809b..dd35ea768ec0fe12fa7fb16060ead60bebd367b2 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -3834,9 +3834,7 @@ parse_matched_pair (int qc, int open, int close, size_t *lenp, int flags)
              continue;
            }
 
-         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
-         if MBTEST(ch == CTLESC)
-           ret[retind++] = CTLESC;
+         RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
          ret[retind++] = ch;
          continue;
        }
index a050ca2c8ad6bb9142e29a18c46b93d59b82fba8..f62efafb6c5cf2487b26d90eff06a0be54a0e847 100644 (file)
--- a/pathexp.c
+++ b/pathexp.c
@@ -104,11 +104,15 @@ unquoted_glob_pattern_p (char *string)
          continue;
 
        case '\\':
-         /* Even after an unquoted backslash, CTLESC either quotes the next
-            char or escapes a CTLESC or CTLNUL.  Either way, the character
-            after it is not an unquoted globbing char. */
          if (*string == CTLESC)
-           string++;
+           {
+             string++;
+             /* If the CTLESC was quoting a CTLESC, skip it so that it's not
+                treated as a quoting character */
+             if (*string == CTLESC)
+               string++;
+           }
+         else
          /*FALLTHROUGH*/
        case CTLESC:
          if (*string++ == '\0')
diff --git a/subst.c b/subst.c
index aa73feadda83013be501ebf44507d98c97e4528d..f6347a4fd7a0e753931a6d882484a4bbdd5e7d93 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -269,7 +269,6 @@ static inline size_t skip_single_quoted (const char *, size_t, size_t, int);
 static int skip_double_quoted (const char *, size_t, size_t, int);
 static char *extract_delimited_string (const char *, size_t *, char *, char *, char *, int);
 static char *extract_heredoc_dolbrace_string (const char *, size_t *, int, int);
-static char *extract_dollar_brace_string (const char *, size_t *, int, int);
 static int skip_matched_pair (const char *, int, int, int, int);
 
 static char *pos_params (const char *, int, int, int, int);
@@ -1805,7 +1804,7 @@ static int dbstate[PARAMEXPNEST_MAX];
    gets the position of the matching `}'.  QUOTED is non-zero if this
    occurs inside double quotes. */
 /* XXX -- this is very similar to extract_delimited_string -- XXX */
-static char *
+char *
 extract_dollar_brace_string (const char *string, size_t *sindex, int quoted, int flags)
 {
   register int i, c;
@@ -4810,14 +4809,6 @@ dequote_string (const char *string)
       return (result);
     }
 
-  /* A string consisting of only a single CTLESC should pass through unchanged */
-  if (string[0] == CTLESC && string[1] == 0)
-    {
-      result[0] = CTLESC;
-      result[1] = '\0';
-      return (result);
-    }
-
   /* If no character in the string can be quoted, don't bother examining
      each character.  Just return a copy of the string passed to us. */
   if (strchr (string, CTLESC) == NULL)
@@ -4827,12 +4818,8 @@ dequote_string (const char *string)
   s = (char *)string;
   while (*s)
     {
-      if (*s == CTLESC)
-       {
-         s++;
-         if (*s == '\0')
-           break;
-       }
+      if (*s == CTLESC && s[1])                /* don't drop trailing CTLESC */
+       s++;
       COPY_CHAR_P (t, s, send);
     }
 
diff --git a/subst.h b/subst.h
index c83bf5a203c5e5ffdac220ab1bcf619b7a36002a..2117e7ccc85fd164b37255cdecd006762fab32ae 100644 (file)
--- a/subst.h
+++ b/subst.h
@@ -103,6 +103,15 @@ extern char *extract_arithmetic_subst (const char *, size_t *);
 extern char *extract_process_subst (const char *, char *, size_t *, int);
 #endif /* PROCESS_SUBSTITUTION */
 
+/* Extract a parameter expansion expression within ${ and } from STRING.
+   Obey the Posix.2 rules for finding the ending `}': count braces while
+   skipping over enclosed quoted strings and command substitutions.
+   SINDEX is the address of an int describing the current offset in STRING;
+   it should point to just after the first `{' found.  On exit, SINDEX
+   gets the position of the matching `}'.  QUOTED is non-zero if this
+   occurs inside double quotes. */
+extern char *extract_dollar_brace_string (const char *, size_t *, int, int);
+
 /* Extract the name of the variable to bind to from the assignment string. */
 extern char *assignment_name (const char *);