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
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.
/* 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
{
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
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;
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);
if (var == 0)
{
free (orig_input_string);
- return (EXECUTION_FAILURE);
+ return (EX_MISCERROR);
}
stupidly_hack_special_variables (varname);
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)
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*/
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;
}
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')
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);
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;
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)
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);
}
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 *);