mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 07:43:07 +02:00
commit bash-20190130 snapshot
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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*>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user