commit bash-20190130 snapshot

This commit is contained in:
Chet Ramey
2019-02-01 09:03:24 -05:00
parent ca5d21091b
commit 8a9718cfc9
17 changed files with 194 additions and 40 deletions
+68
View File
@@ -5122,3 +5122,71 @@ builtins/complete.def
mode characters and doesn't contain any shell break characters that
would need to be quoted when defining a function. Fixes issue
reported by Great Big Dot <greatbigdot@gmail.com>
1/28
----
variables.c
- dispose_temporary_env: make sure to save temporary_env to a temp
pointer and set temporary_env to NULL before trying to dispose it,
so no flush function ever tries to add a temporary variable back
into the table (e.g., bind_variable())
1/29
----
builtins/evalstring.c
- can_optimize_connection,optimize_fork: add the last command in lists
separated by `;' to the list of candidates for fork optimization
1/30
----
examples/loadables/strftime.c
- strftime_builtin: try to extend the buffer longer than tbsize*3,
which is a minimum of 24 characters, in case some of the formats
(e.g., %c) expand to something longer than that. Fixes bug
reported by Stan Marsh <gazelle@xmission.com>
1/31
----
lib/readline/undo.c
- rl_do_undo: before inserting text while undoing UNDO_DELETE, or
performing a deletion while undoing UNDO_INSERT, make sure that
rl_point is valid by calling _rl_fix_point. Fuzzing bug and fix
from Eduardo Bustamante <dualbus@gmail.com>
lib/readline/search.c
- _rl_nsearch_abort: validate new values for rl_point and rl_mark by
calling _rl_fix_point(). Fuzzing bug and fix from
Eduardo Bustamante <dualbus@gmail.com>
subst.c
- string_extract_double_quoted: if we parse a syntactically-incorrect
$( expression while extracting a double-quoted string, si will
appear to go `backward'. Just skip over the rest of the string and
continue. Fuzzing bug from Eduardo Bustamante <dualbus@gmail.com>
lib/readline/text.c
- rl_change_case: if towupper or towlower returns a valid wide char
that can't be converted back to a valid multibyte character, use
the original character and go on. Fuzzing bug from
Eduardo Bustamante <dualbus@gmail.com>
lib/glob/glob.c
- wdequote_pathname: if there are no multibyte characters in pathname,
just call udequote_pathname and don't bother converting it to wide
characters
- glob_pattern_p: if there are no multibyte characters in the pattern,
just call internal_glob_pattern_p right away
lib/glob/glob_loop.c
- INTERNAL_GLOB_PATTERN_P: return 2 if we see only backslash-quoted
characters without any other unquoted glob pattern characters, so
interested callers can shortcut and just dequote the pathname
pathexp.c
- unquoted_glob_pattern_p: return 2 if we see only backslash-quoted
characters without any other unquoted glob pattern characters,
consistent with the glob library
- unquoted_glob_pattern_p: don't count a backslash quoting a slash as
a backslash that will trigger a call to shell_glob_filename, since
backslashes at the end of patterns (pathname components) will always
fail to match. XXX - this is provisional
+1
View File
@@ -1060,6 +1060,7 @@ tests/glob1.sub f
tests/glob2.sub f
tests/glob3.sub f
tests/glob4.sub f
tests/glob5.sub f
tests/glob.right f
tests/globstar.tests f
tests/globstar.right f
+2 -2
View File
@@ -105,7 +105,7 @@ can_optimize_connection (command)
COMMAND *command;
{
return (*bash_input.location.string == '\0' &&
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR) &&
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') &&
command->value.Connection->second->type == cm_simple);
}
@@ -114,7 +114,7 @@ optimize_fork (command)
COMMAND *command;
{
if (command->type == cm_connection &&
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR) &&
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') &&
(command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) &&
should_suppress_fork (command->value.Connection->second))
{
+3 -2
View File
@@ -86,7 +86,7 @@ strftime_builtin (list)
/* Now try to figure out how big the buffer should really be. strftime(3)
will return the number of bytes placed in the buffer unless it's greater
than MAXSIZE, in which case it returns 0. */
for (n = 1; n < 4; n++)
for (n = 1; n <= 8; n++)
{
tbuf = xrealloc (tbuf, tbsize * n);
tsize = strftime (tbuf, tbsize * n, format, t);
@@ -94,7 +94,8 @@ strftime_builtin (list)
break;
}
printf ("%s\n", tbuf);
if (tsize)
printf ("%s\n", tbuf);
free (tbuf);
return (EXECUTION_SUCCESS);
+19 -5
View File
@@ -159,7 +159,7 @@ glob_pattern_p (pattern)
wchar_t *wpattern;
int r;
if (MB_CUR_MAX == 1)
if (MB_CUR_MAX == 1 || mbsmbchar (pattern) == 0)
return (internal_glob_pattern_p ((unsigned char *)pattern));
/* Convert strings to wide chars, and call the multibyte version. */
@@ -173,7 +173,7 @@ glob_pattern_p (pattern)
return r;
#else
return (internal_glob_pattern_p (pattern));
return (internal_glob_pattern_p ((unsigned char *)pattern));
#endif
}
@@ -431,6 +431,12 @@ wdequote_pathname (pathname)
int i, j;
wchar_t *orig_wpathname;
if (mbsmbchar (pathname) == 0)
{
udequote_pathname (pathname);
return;
}
len = strlen (pathname);
/* Convert the strings into wide characters. */
n = xdupmbstowcs (&wpathname, NULL, pathname);
@@ -1071,7 +1077,7 @@ glob_filename (pathname, flags)
char *directory_name, *filename, *dname, *fn;
unsigned int directory_len;
int free_dirname; /* flag */
int dflags;
int dflags, hasglob;
result = (char **) malloc (sizeof (char *));
result_size = 1;
@@ -1120,9 +1126,12 @@ glob_filename (pathname, flags)
free_dirname = 1;
}
hasglob = 0;
/* If directory_name contains globbing characters, then we
have to expand the previous levels. Just recurse. */
if (directory_len > 0 && glob_pattern_p (directory_name))
have to expand the previous levels. Just recurse.
If glob_pattern_p returns != [0,1] we have a pattern that has backslash
quotes but no unquoted glob pattern characters. We dequote it below. */
if (directory_len > 0 && (hasglob = glob_pattern_p (directory_name)) == 1)
{
char **directories, *d, *p;
register unsigned int i;
@@ -1342,6 +1351,11 @@ only_filename:
free (directory_name);
return (NULL);
}
if (directory_len > 0 && hasglob == 2) /* need to dequote */
{
dequote_pathname (directory_name);
directory_len = strlen (directory_name);
}
/* Handle GX_MARKDIRS here. */
result[0] = (char *) malloc (directory_len + 1);
if (result[0] == NULL)
+16 -7
View File
@@ -26,10 +26,10 @@ INTERNAL_GLOB_PATTERN_P (pattern)
{
register const GCHAR *p;
register GCHAR c;
int bopen;
int bopen, bsquote;
p = pattern;
bopen = 0;
bopen = bsquote = 0;
while ((c = *p++) != L('\0'))
switch (c)
@@ -55,13 +55,22 @@ INTERNAL_GLOB_PATTERN_P (pattern)
case L('\\'):
/* Don't let the pattern end in a backslash (GMATCH returns no match
if the pattern ends in a backslash anyway), but otherwise return 1,
since the matching engine uses backslash as an escape character
and it can be removed. */
return (*p != L('\0'));
if the pattern ends in a backslash anyway), but otherwise note that
we have seen this, since the matching engine uses backslash as an
escape character and it can be removed. We return 2 later if we
have seen only backslash-escaped characters, so interested callers
know they can shortcut and just dequote the pathname. */
if (*p != L('\0'))
{
p++;
bsquote = 1;
}
else if (*p == L('\0'))
return 0;
continue;
}
return 0;
return bsquote ? 2 : 0;
}
#undef INTERNAL_GLOB_PATTERN_P
+1 -1
View File
@@ -529,7 +529,7 @@ xstrmatch (pattern, string, flags)
if (MB_CUR_MAX == 1)
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
if (mbsmbchar (string) == 0 && mbsmbchar (pattern) == 0 && posix_cclass_only (pattern) )
if (mbsmbchar (string) == 0 && mbsmbchar (pattern) == 0 && posix_cclass_only (pattern))
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
n = xdupmbstowcs (&wpattern, NULL, pattern);
+1
View File
@@ -256,6 +256,7 @@ _rl_nsearch_abort (_rl_search_cxt *cxt)
rl_clear_message ();
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
_rl_fix_point (1);
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
+12 -1
View File
@@ -1452,7 +1452,18 @@ rl_change_case (int count, int op)
if (nwc != wc) /* just skip unchanged characters */
{
char *s, *e;
mlen = wcrtomb (mb, nwc, &mps);
mbstate_t ts;
memset (&ts, 0, sizeof (mbstate_t));
mlen = wcrtomb (mb, nwc, &ts);
if (mlen < 0)
{
nwc = wc;
memset (&ts, 0, sizeof (mbstate_t));
mlen = wcrtomb (mb, nwc, &ts);
if (mlen < 0) /* should not happen */
strncpy (mb, rl_line_buffer + start, mlen = m);
}
if (mlen > 0)
mb[mlen] = '\0';
/* what to do if m != mlen? adjust below */
+2
View File
@@ -196,6 +196,7 @@ rl_do_undo (void)
/* Undoing deletes means inserting some text. */
case UNDO_DELETE:
rl_point = start;
_rl_fix_point (1);
rl_insert_text (rl_undo_list->text);
xfree (rl_undo_list->text);
break;
@@ -204,6 +205,7 @@ rl_do_undo (void)
case UNDO_INSERT:
rl_delete_text (start, end);
rl_point = start;
_rl_fix_point (1);
break;
/* Undoing an END means undoing everything 'til we get to a BEGIN. */
+12 -4
View File
@@ -65,11 +65,11 @@ unquoted_glob_pattern_p (string)
{
register int c;
char *send;
int open;
int open, bsquote;
DECLARE_MBSTATE;
open = 0;
open = bsquote = 0;
send = string + strlen (string);
while (c = *string++)
@@ -100,7 +100,14 @@ unquoted_glob_pattern_p (string)
can be removed by the matching engine, so we have to run it through
globbing. */
case '\\':
return (*string != 0);
if (*string != '\0' && *string != '/')
{
bsquote = 1;
string++;
continue;
}
else if (*string == 0)
return (0);
case CTLESC:
if (*string++ == '\0')
@@ -117,7 +124,8 @@ unquoted_glob_pattern_p (string)
ADVANCE_CHAR_P (string, send - string);
#endif
}
return (0);
return (bsquote ? 2 : 0);
}
/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
+3 -1
View File
@@ -964,7 +964,9 @@ add_one_character:
temp[j] = ret[t];
temp[j] = string[si];
if (string[si])
if (si < i + 2) /* we went back? */
i += 2;
else if (string[si])
{
j++;
i = si + 1;
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
BUILD_DIR=/usr/local/build/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+7 -1
View File
@@ -63,6 +63,12 @@ a?
aa
<define\/\
/>
/tmp/a/b/c /tmp/a/b/c /tmp/a/b/c
/tmp/a/b/c /tmp/a/b/c /tmp/a/b/c
/tmp/a/b/c
/tmp/a/b/c
/tmp\/a/b/c
/tm[p]\/a/b/c
argv[1] = <a>
argv[2] = <abc>
argv[3] = <abd>
@@ -77,7 +83,7 @@ argv[2] = <abc>
argv[3] = <abd>
argv[4] = <abe>
tmp/l1 tmp/l2 tmp/*4 tmp/l3
./glob.tests: line 47: no match: tmp/*4
./glob.tests: line 48: no match: tmp/*4
argv[1] = <bdir/>
argv[1] = <*>
argv[1] = <a*>
+1
View File
@@ -12,6 +12,7 @@ ${THIS_SH} ./glob1.sub
${THIS_SH} ./glob2.sub
${THIS_SH} ./glob3.sub
${THIS_SH} ./glob4.sub
${THIS_SH} ./glob5.sub
MYDIR=$PWD # save where we are
+16
View File
@@ -0,0 +1,16 @@
mkdir -m700 /tmp/a /tmp/a/b
touch /tmp/a/b/c
echo /tmp/a/b/* "/tmp/a/"b/* "/tmp/a/b"/*
chmod -r /tmp/a
echo /tmp/a/b/* "/tmp/a/"b/* "/tmp/a/b"/*
echo "/tmp/a/b"/*
bs=\\
echo /tmp${bs}/a/b/*
echo /tmp${bs}/a/b/c
echo /tm[p]${bs}/a/b/c
chmod +r /tmp/a
rm -rf /tmp/a
+29 -15
View File
@@ -3270,12 +3270,7 @@ bind_variable (name, value, flags)
else if (nv == &nameref_maxloop_value)
{
internal_warning (_("%s: circular name reference"), v->name);
#if 1
/* TAG:bash-5.1 */
return (bind_global_variable (v->name, value, flags));
#else
v = 0; /* backwards compat */
#endif
}
else
v = nv;
@@ -3283,12 +3278,7 @@ bind_variable (name, value, flags)
else if (nv == &nameref_maxloop_value)
{
internal_warning (_("%s: circular name reference"), v->name);
#if 1
/* TAG:bash-5.1 */
return (bind_global_variable (v->name, value, flags));
#else
v = 0; /* backwards compat */
#endif
}
else
v = nv;
@@ -4472,16 +4462,37 @@ push_posix_temp_var (data)
var = (SHELL_VAR *)data;
#if 0 /* TAG:bash-5.1 */
/* Just like do_assignment_internal(). This makes assignments preceding
special builtins act like standalone assignment statements when in
posix mode. */
v = bind_variable (var->name, value_cell (var), ASS_FORCE|ASS_NOLONGJMP);
/* If this modifies an existing local variable, v->context will be non-zero.
If it comes back with v->context == 0, we bound at the global context.
Set binding_table appropriately. It doesn't matter whether it's correct
if the variable is local, only that it's not global_variables->table */
binding_table = v->context ? shell_variables->table : global_variables->table;
#else
binding_table = global_variables->table;
if (binding_table == 0)
binding_table = global_variables->table = hash_create (VARIABLES_HASH_BUCKETS);
v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, ASS_FORCE|ASS_NOLONGJMP);
#endif
/* global variables are no longer temporary and don't need propagating. */
var->attributes &= ~(att_tempvar|att_propagate);
if (binding_table == global_variables->table)
var->attributes &= ~(att_tempvar|att_propagate);
if (v)
v->attributes |= var->attributes;
{
v->attributes |= var->attributes;
v->attributes &= ~att_tempvar; /* not a temp var now */
#if 1 /* TAG:bash-5.1 code doesn't need this, disable for bash-5.1 */
v->context = (binding_table == global_variables->table) ? 0 : shell_variables->scope;
#endif
}
if (find_special_var (var->name) >= 0)
tempvar_list[tvlist_ind++] = savestring (var->name);
@@ -4575,14 +4586,17 @@ dispose_temporary_env (pushf)
sh_free_func_t *pushf;
{
int i;
HASH_TABLE *disposer;
tempvar_list = strvec_create (HASH_ENTRIES (temporary_env) + 1);
tempvar_list[tvlist_ind = 0] = 0;
hash_flush (temporary_env, pushf);
hash_dispose (temporary_env);
disposer = temporary_env;
temporary_env = (HASH_TABLE *)NULL;
hash_flush (disposer, pushf);
hash_dispose (disposer);
tempvar_list[tvlist_ind] = 0;
array_needs_making = 1;