mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-02 01:40:49 +02:00
fix for printing case pattern lists beginning with "esac"; several fixes for expansion when IFS contains DEL
This commit is contained in:
@@ -8750,3 +8750,30 @@ lib/readline/display.c
|
||||
- update_line: use IS_COMBINING_CHAR instead of UNICODE_COMBINING_CHAR
|
||||
plus WCWIDTH; it doesn't make sense on systems where wcwidth isn't
|
||||
broken
|
||||
|
||||
2/27
|
||||
----
|
||||
print_cmd.c
|
||||
- print_case_clauses: if one of the case command pattern lists begins
|
||||
with the word `esac' (unquoted), precede the pattern list with `(',
|
||||
since it had to be there originally to get through the parser.
|
||||
Report by Emanuele Torre <torreemanuele6@gmail.com>
|
||||
|
||||
2/29
|
||||
----
|
||||
general.c,general.h
|
||||
- string_to_rlimtype: takes a second ENDP argument, like strtol, so
|
||||
the caller doesn't have to check that the string is all digits,
|
||||
but can optionally check for and disallow a 0x prefix
|
||||
|
||||
3/2
|
||||
---
|
||||
subst.c
|
||||
- dequote_list: unset the W_QUOTED flag in the word after dequoting it
|
||||
- parameter_brace_expand_rhs: if the word in the list returned by
|
||||
expand_string_for_rhs has W_QUOTED set, but the string being
|
||||
expanded was not quoted, turn on the W_QUOTED in the returned word
|
||||
so we can potentially avoid word splitting
|
||||
- expand_word_internal: if CTLNUL is a IFS character, don't add quoted
|
||||
null strings to istring if we're going to be word splitting, since
|
||||
they will be treated as word delimiters
|
||||
|
||||
+11
-3
@@ -94,6 +94,7 @@ $END
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
#include "pipesize.h"
|
||||
#include <chartypes.h>
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
@@ -131,7 +132,7 @@ extern int errno;
|
||||
|
||||
#if !defined (RLIMTYPE)
|
||||
# define RLIMTYPE long
|
||||
# define string_to_rlimtype(s) strtol(s, (char **)NULL, 10)
|
||||
# define string_to_rlimtype(s, ep) strtol(s, ep, 10)
|
||||
# define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "")
|
||||
#endif
|
||||
|
||||
@@ -473,9 +474,16 @@ ulimit_internal (int cmd, char *cmdarg, int mode, int multiple)
|
||||
real_limit = soft_limit;
|
||||
else if (STREQ (cmdarg, "unlimited"))
|
||||
real_limit = RLIM_INFINITY;
|
||||
else if (all_digits (cmdarg))
|
||||
else if (DIGIT (*cmdarg) && (cmdarg[1] == 0 || DIGIT (cmdarg[1])))
|
||||
{
|
||||
limit = string_to_rlimtype (cmdarg);
|
||||
char *endp;
|
||||
limit = string_to_rlimtype (cmdarg, &endp);
|
||||
if (*endp != '\0')
|
||||
{
|
||||
sh_invalidnum (cmdarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
block_factor = BLOCKSIZE(limits[limind].block_factor);
|
||||
real_limit = limit * block_factor;
|
||||
|
||||
|
||||
@@ -170,15 +170,17 @@ set_posix_options (const char *bitmap)
|
||||
|
||||
#if defined (RLIMTYPE)
|
||||
RLIMTYPE
|
||||
string_to_rlimtype (char *s)
|
||||
string_to_rlimtype (const char *string, char **ep)
|
||||
{
|
||||
RLIMTYPE ret;
|
||||
int neg;
|
||||
const char *s;
|
||||
|
||||
ret = 0;
|
||||
neg = 0;
|
||||
s = string;
|
||||
/* ulimit_builtin doesn't allow leading whitespace or an optional
|
||||
leading `+' or `-'. */
|
||||
leading `+' or `-', so the caller has to check. */
|
||||
while (s && *s && whitespace (*s))
|
||||
s++;
|
||||
if (s && (*s == '-' || *s == '+'))
|
||||
@@ -188,6 +190,8 @@ string_to_rlimtype (char *s)
|
||||
}
|
||||
for ( ; s && *s && DIGIT (*s); s++)
|
||||
ret = (ret * 10) + TODIGIT (*s);
|
||||
if (ep)
|
||||
*ep = (char *)s;
|
||||
return (neg ? -ret : ret);
|
||||
}
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ extern void set_posix_options (const char *);
|
||||
extern void save_posix_options (void);
|
||||
|
||||
#if defined (RLIMTYPE)
|
||||
extern RLIMTYPE string_to_rlimtype (char *);
|
||||
extern RLIMTYPE string_to_rlimtype (const char *, char **);
|
||||
extern void print_rlimtype (RLIMTYPE, int);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -771,6 +771,14 @@ print_case_clauses (PATTERN_LIST *clauses)
|
||||
if (printing_comsub == 0 || first == 0)
|
||||
newline ("");
|
||||
first = 0;
|
||||
/* "The grammar shows that reserved words can be used as patterns,
|
||||
even if one is the first word on a line. Obviously, the reserved
|
||||
word esac cannot be used in this manner." */
|
||||
/* If the first word of the pattern list is literal "esac", the only
|
||||
way it could have gotten through the parser is to have been
|
||||
preceded by a left paren. */
|
||||
if (STREQ (clauses->patterns->word->word, "esac"))
|
||||
cprintf("(");
|
||||
command_print_word_list (clauses->patterns, " | ");
|
||||
cprintf (")\n");
|
||||
indentation += indentation_amount;
|
||||
|
||||
@@ -252,6 +252,9 @@ static WORD_LIST *expand_string_for_pat (const char *, int, int *, int *);
|
||||
|
||||
static char *quote_escapes_internal (const char *, int);
|
||||
|
||||
static char *quote_ifs (const char *);
|
||||
static WORD_LIST *list_quote_ifs (WORD_LIST *);
|
||||
|
||||
static WORD_LIST *list_quote_escapes (WORD_LIST *);
|
||||
static WORD_LIST *list_dequote_escapes (WORD_LIST *);
|
||||
|
||||
@@ -4478,6 +4481,8 @@ expand_string_for_rhs (const char *string, int quoted, int op, int pflags, int *
|
||||
/* This was further clarified on the austin-group list in March, 2017 and
|
||||
in Posix bug 1129 */
|
||||
old_nosplit = expand_no_split_dollar_star;
|
||||
/* The check against ifs_is_null is so we don't split this time through,
|
||||
since we will split the (possibly-quoted) results of this function. */
|
||||
expand_no_split_dollar_star = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || op == '=' || ifs_is_null == 0; /* XXX - was 1 */
|
||||
td.flags = W_EXPANDRHS; /* expanding RHS of ${paramOPword} */
|
||||
td.flags |= W_NOSPLIT2; /* no splitting, remove "" and '' */
|
||||
@@ -4884,6 +4889,7 @@ dequote_list (WORD_LIST *list)
|
||||
tlist->word->flags &= ~W_HASQUOTEDNULL;
|
||||
free (tlist->word->word);
|
||||
tlist->word->word = s;
|
||||
tlist->word->flags &= ~W_QUOTED; /* no longer quoted */
|
||||
}
|
||||
return list;
|
||||
}
|
||||
@@ -4905,6 +4911,47 @@ remove_quoted_escapes (char *string)
|
||||
return (string);
|
||||
}
|
||||
|
||||
/* Use CTLESC to quote IFS characters in STRING. Not used yet. */
|
||||
static char *
|
||||
quote_ifs (const char *string)
|
||||
{
|
||||
const char *s, *send;
|
||||
char *t, *result;
|
||||
size_t slen;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
slen = strlen (string);
|
||||
send = string + slen;
|
||||
|
||||
t = result = (char *)xmalloc ((slen * 2) + 1);
|
||||
s = string;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
if (isifs (*s))
|
||||
*t++ = CTLESC;
|
||||
COPY_CHAR_P (t, s, send);
|
||||
}
|
||||
*t = '\0';
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static WORD_LIST *
|
||||
list_quote_ifs (WORD_LIST *list)
|
||||
{
|
||||
WORD_LIST *w;
|
||||
char *t;
|
||||
|
||||
for (w = list; w; w = w->next)
|
||||
{
|
||||
t = w->word->word;
|
||||
w->word->word = quote_ifs (t);
|
||||
free (t);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Remove quoted $IFS characters from STRING. Quoted IFS characters are
|
||||
added to protect them from word splitting, but we need to remove them
|
||||
if no word splitting takes place. This returns newly-allocated memory,
|
||||
@@ -7986,6 +8033,8 @@ parameter_brace_expand_rhs (char *name, char *value,
|
||||
temp = string_list (l);
|
||||
if (temp && (QUOTED_NULL (temp) == 0) && (l->word->flags & W_SAWQUOTEDNULL))
|
||||
w->flags |= W_SAWQUOTEDNULL; /* XXX */
|
||||
if (temp && (l->word->flags & W_QUOTED) && quoted == 0)
|
||||
w->flags |= W_QUOTED;
|
||||
}
|
||||
|
||||
/* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
|
||||
@@ -10524,6 +10573,7 @@ param_expand (char *string, size_t *sindex, int quoted,
|
||||
temp = string_list_dollar_star (list, quoted, 0);
|
||||
if (temp)
|
||||
{
|
||||
/* Q_HERE_DOCUMENT as well? */
|
||||
temp1 = (quoted & Q_DOUBLE_QUOTES) ? quote_string (temp) : temp;
|
||||
if (*temp == 0)
|
||||
tflag |= W_HASQUOTEDNULL;
|
||||
@@ -10593,11 +10643,7 @@ param_expand (char *string, size_t *sindex, int quoted,
|
||||
temp = string_list_dollar_at (list, quoted, 0);
|
||||
/* Set W_SPLITSPACE to make sure the individual positional
|
||||
parameters are split into separate arguments */
|
||||
#if 0
|
||||
if (quoted == 0 && (ifs_is_set == 0 || ifs_is_null))
|
||||
#else /* change with bash-5.0 */
|
||||
if (quoted == 0 && ifs_is_null)
|
||||
#endif
|
||||
tflag |= W_SPLITSPACE;
|
||||
/* If we're not quoted but we still don't want word splitting, make
|
||||
we quote the IFS characters to protect them from splitting (e.g.,
|
||||
@@ -11437,6 +11483,12 @@ add_string:
|
||||
if (tword && (tword->flags & W_SAWQUOTEDNULL))
|
||||
had_quoted_null = 1; /* XXX */
|
||||
|
||||
/* This loses tword->flags. If quoted == 0 but (tword->flags & W_QUOTED),
|
||||
we need to note that somewhere. It means that the result will be
|
||||
split, but this portion should not be. It only really matters if
|
||||
$IFS contains $'\001', since usually quoting with CTLESC will
|
||||
inhibit the word splitting. */
|
||||
|
||||
temp = tword ? tword->word : (char *)NULL;
|
||||
dispose_word_desc (tword);
|
||||
|
||||
@@ -11724,6 +11776,10 @@ add_twochars:
|
||||
will cause word splitting. */
|
||||
if (temp == 0 && quoted_state == PARTIALLY_QUOTED && quoted == 0 && (word->flags & (W_NOSPLIT|W_EXPANDRHS|W_ASSIGNRHS)) == W_EXPANDRHS)
|
||||
{
|
||||
/* Don't add a quoted null character if it would eventually be
|
||||
used as a word delimiter when splitting. */
|
||||
if (isifs (CTLNUL))
|
||||
continue;
|
||||
c = CTLNUL;
|
||||
sindex--;
|
||||
had_quoted_null = 1;
|
||||
@@ -11732,6 +11788,11 @@ add_twochars:
|
||||
if (temp == 0 && quoted_state == PARTIALLY_QUOTED && (word->flags & (W_NOSPLIT|W_NOSPLIT2)))
|
||||
continue;
|
||||
|
||||
/* Throw away a quoted null instead of adding a character that
|
||||
would eventually be a word delimiter when splitting. */
|
||||
if (temp == 0 && quoted_state == PARTIALLY_QUOTED && had_quoted_null && isifs(CTLNUL))
|
||||
continue;
|
||||
|
||||
add_quoted_string:
|
||||
|
||||
if (temp)
|
||||
|
||||
Reference in New Issue
Block a user