mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-29 00:19:51 +02:00
changes for backslashes in glob patterns and single-quoted strings; brace expansion knows '${...}' expansions; read returns status 2 if trying to assign to a readonly variable
This commit is contained in:
+40
-1
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
+3
-3
@@ -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);
|
||||
|
||||
+4
-2
@@ -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*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user