commit bash-20191004 snapshot

This commit is contained in:
Chet Ramey
2019-10-07 11:02:34 -04:00
parent 41e92b981d
commit f7ec6b1a00
18 changed files with 329 additions and 102 deletions
+71 -1
View File
@@ -6655,4 +6655,74 @@ doc/{bash.1,bashref.texi}
- mark_dead_jobs_as_notified: call set_maxchild to set js.c_childmax
if it hasn't been set yet
9/30
----
lib/glob/xmbsrtowcs.c
- xwcsrtombs: implementation of wcsrtombs from gnulib, modified to
treat invalid wide characters (or wide characters that can't be
converted to multibyte character sequences) as bytes. Should be
used only in unusual circumstances where wcsrtombs fails.
lib/glob/glob.c
- wdequote_pathname: if wcsrtombs fails to convert the dequoted wide
character pathname back to a sequence of multibyte characters, call
xwcsrtombs to try to treat the invalid wide characters as bytes --
the call to xdupmbstowcs treats bytes that don't convert to wide
characters as just bytes, which kind of causes this problem in the
first place. Inspired by report from Geoff Kuenning <geoff@cs.hmc.edu>
lib/readline/complete.c
- compute_lcd_of_matches: use the case-folding code (which performs
character-by-character checking and compares invalid multibyte
sequences as bytes) instead of the old case-sensitive code (which
used _rl_compare_chars), converting characters to lowercase as
needed. Fixes bug with invalid sequences in common filename prefixes
reported by Grisha Levit <grishalevit@gmail.com>
10/1
----
builtins/shopt.def
- reset_shopt_options: add in resets for some missing shopt options.
Report and fix from Grisha Levit <grishalevit@gmail.com>
execute_cmd.c
- execute_command_internal: make sure a failed attempt to define a
shell function causes the shell to exit if -e is enabled. Report
from Andreas Kusalananda K盲h盲ri <andreas.kahari@abc.se>
- execute_command_internal: combine cm_function_def, cm_arith, and
cm_cond cases into one switch case, since the code is virtually
identical across all three
10/3
----
pathexp.[ch],lib/glob/glob.c,lib/glob/glob_loop.c
- remove all references to posix_glob_backslash in preparation for
implementing austin group interpretation #1234
pathexp.c
- unquoted_glob_pattern_p: revert to bash-4.4 behavior of returning 1
only if there is an unquoted `*', `?', or bracket expression, as
per austin group interpretation #1234
lib/glob/glob_loop.c
- INTERNAL_GLOB_PATTERN_P: revert to bash-4.4 behavior of returning 1
only if there is an unquoted `*', `?', or bracket expression, as
per austin group interpretation #1234
10/4
----
variables.c
- assign_seconds,get_seconds: use the tv_sec value returned from
gettimeofday() instead of time() to get a better approximation of
the number of seconds since the epoch for future calculations.
From a report by Stephane Chazelas <stephane.chazelas@gmail.com>
pathexp.[ch],{bashline,subst}.c
- shell_glob_filename: now takes an additional flags argument to pass
to quote_string_for_globbing
10/6
----
subst.c
- glob_expand_word_list: call shell_glob_filename with QGLOB_CTLESC
because quote removal hasn't been performed yet
+2 -1
View File
@@ -1383,7 +1383,8 @@ tests/set-e.right f
tests/set-x.tests f
tests/set-x1.sub f
tests/set-x.right f
tests/shopt.tests f
tests/shopt.tests f
tests/shopt1.sub f
tests/shopt.right f
tests/strip.tests f
tests/strip.right f
+2 -2
View File
@@ -2140,7 +2140,7 @@ globword:
if (state == 0)
{
glob_ignore_case = igncase;
glob_matches = shell_glob_filename (hint);
glob_matches = shell_glob_filename (hint, 0);
glob_ignore_case = old_glob_ignore_case;
if (GLOB_FAILED (glob_matches) || glob_matches == 0)
@@ -3891,7 +3891,7 @@ glob_complete_word (text, state)
if (ttext != text)
free (ttext);
matches = shell_glob_filename (globtext);
matches = shell_glob_filename (globtext, 0);
if (GLOB_FAILED (matches))
matches = (char **)NULL;
ind = 0;
+8
View File
@@ -347,6 +347,7 @@ reset_shopt_options ()
inherit_errexit = 0;
interactive_comments = 1;
lastpipe_opt = 0;
localvar_inherit = localvar_unset = 0;
mail_warning = 0;
glob_ignore_case = match_ignore_case = 0;
print_shift_error = 0;
@@ -360,6 +361,10 @@ reset_shopt_options ()
extended_glob = EXTGLOB_DEFAULT;
#endif
#if defined (ARRAY_VARS)
assoc_expand_once = 0;
#endif
#if defined (HISTORY)
literal_history = 0;
force_append_history = 0;
@@ -390,6 +395,9 @@ reset_shopt_options ()
#if defined (PROGRAMMABLE_COMPLETION)
prog_completion_enabled = 1;
# if defined (ALIAS)
progcomp_alias = 0;
# endif
#endif
#if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX)
+22 -33
View File
@@ -1002,40 +1002,35 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
#if defined (DPAREN_ARITHMETIC)
case cm_arith:
was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
if (ignore_return)
command->value.Arith->flags |= CMD_IGNORE_RETURN;
line_number_for_err_trap = save_line_number = line_number;
exec_result = execute_arith_command (command->value.Arith);
line_number = save_line_number;
if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
{
last_command_exit_value = exec_result;
save_line_number = line_number;
line_number = line_number_for_err_trap;
run_error_trap ();
line_number = save_line_number;
}
if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
{
last_command_exit_value = exec_result;
run_pending_traps ();
jump_to_top_level (ERREXIT);
}
break;
#endif
#if defined (COND_COMMAND)
case cm_cond:
#endif
case cm_function_def:
was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
if (ignore_return)
#if defined (DPAREN_ARITHMETIC)
if (ignore_return && command->type == cm_arith)
command->value.Arith->flags |= CMD_IGNORE_RETURN;
#endif
#if defined (COND_COMMAND)
if (ignore_return && command->type == cm_cond)
command->value.Cond->flags |= CMD_IGNORE_RETURN;
#endif
line_number_for_err_trap = save_line_number = line_number;
exec_result = execute_cond_command (command->value.Cond);
#if defined (DPAREN_ARITHMETIC)
if (command->type == cm_arith)
exec_result = execute_arith_command (command->value.Arith);
else
#endif
#if defined (COND_COMMAND)
if (command->type == cm_cond)
exec_result = execute_cond_command (command->value.Cond);
else
#endif
if (command->type == cm_function_def)
exec_result = execute_intern_function (command->value.Function_def->name,
command->value.Function_def);
line_number = save_line_number;
if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
@@ -1055,12 +1050,6 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
}
break;
#endif
case cm_function_def:
exec_result = execute_intern_function (command->value.Function_def->name,
command->value.Function_def);
break;
default:
command_error ("execute_command", CMDERR_BADTYPE, command->type, 0);
+1
View File
@@ -246,6 +246,7 @@ typedef int sh_builtin_func_t __P((WORD_LIST *)); /* sh_wlist_func_t */
#endif /* SH_FUNCTION_TYPEDEF */
#define NOW ((time_t) time ((time_t *) 0))
#define GETTIME(tv) gettimeofday(&(tv), NULL)
/* Some defines for calling file status functions. */
#define FS_EXISTS 0x1
-4
View File
@@ -2834,11 +2834,7 @@ raw_job_exit_status (job)
int fail;
WAIT ret;
#if 0
if (pipefail_opt)
#else
if (jobs[job]->flags & J_PIPEFAIL)
#endif
{
fail = 0;
p = jobs[job]->pipe;
+6 -5
View File
@@ -91,7 +91,6 @@ extern int signal_is_pending __P((int));
extern void run_pending_traps __P((void));
extern int extended_glob;
extern int posix_glob_backslash;
/* Global variable which controls whether or not * matches .*.
Non-zero means don't match .*. */
@@ -475,6 +474,12 @@ wdequote_pathname (pathname)
/* Convert the wide character string into unibyte character set. */
memset (&ps, '\0', sizeof(mbstate_t));
n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
if (n == (size_t)-1 || *wpathname != 0) /* what? now you tell me? */
{
wpathname = orig_wpathname;
memset (&ps, '\0', sizeof(mbstate_t));
n = xwcsrtombs (pathname, (const wchar_t **)&wpathname, len, &ps);
}
pathname[len] = '\0';
/* Can't just free wpathname here; wcsrtombs changes it in many cases. */
@@ -1421,7 +1426,6 @@ only_filename:
if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) == 0)
{
#if 1
dequote_pathname (directory_name);
if (glob_testdir (directory_name, 0) < 0)
{
@@ -1429,9 +1433,6 @@ only_filename:
free (directory_name);
return ((char **)&glob_error_return);
}
#else
return ((char **)&glob_error_return);
#endif
}
/* Handle GX_MARKDIRS here. */
+5 -1
View File
@@ -70,7 +70,11 @@ INTERNAL_GLOB_PATTERN_P (pattern)
return 0;
}
return ((bsquote && posix_glob_backslash) ? 2 : 0);
#if 0
return bsquote ? 2 : 0;
#else
return (0);
#endif
}
#undef INTERNAL_GLOB_PATTERN_P
+115 -1
View File
@@ -1,6 +1,6 @@
/* xmbsrtowcs.c -- replacement function for mbsrtowcs */
/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
/* Copyright (C) 2002-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -35,6 +35,11 @@
#if HANDLE_MULTIBYTE
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif
#define WSBUF_INC 32
#ifndef FREE
@@ -406,4 +411,113 @@ xdupmbstowcs (destp, indicesp, src)
return (wcnum - 1);
}
/* Convert wide character string to multibyte character string. Treat invalid
wide characters as bytes. Used only in unusual circumstances.
Written by Bruno Haible <bruno@clisp.org>, 2008, adapted by Chet Ramey
for use in Bash. */
/* Convert wide character string *SRCP to a multibyte character string and
store the result in DEST. Store at most LEN bytes in DEST. */
size_t
xwcsrtombs (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps)
{
const wchar_t *src;
size_t cur_max; /* XXX - locale_cur_max */
char buf[64], *destptr, *tmp_dest;
unsigned char uc;
mbstate_t prev_state;
cur_max = MB_CUR_MAX;
if (cur_max > sizeof (buf)) /* Holy cow. */
return (size_t)-1;
src = *srcp;
if (dest != NULL)
{
destptr = dest;
for (; len > 0; src++)
{
wchar_t wc;
size_t ret;
wc = *src;
/* If we have room, store directly into DEST. */
tmp_dest = destptr;
ret = wcrtomb (len >= cur_max ? destptr : buf, wc, ps);
if (ret == (size_t)(-1)) /* XXX */
{
/* Since this is used for globbing and other uses of filenames,
treat invalid wide character sequences as bytes. This is
intended to be symmetric with xdupmbstowcs2. */
handle_byte:
destptr = tmp_dest; /* in case wcrtomb modified it */
uc = wc;
ret = 1;
if (len >= cur_max)
*destptr = uc;
else
buf[0] = uc;
if (ps)
memset (ps, 0, sizeof (mbstate_t));
}
if (ret > cur_max) /* Holy cow */
goto bad_input;
if (len < ret)
break;
if (len < cur_max)
memcpy (destptr, buf, ret);
if (wc == 0)
{
src = NULL;
/* Here mbsinit (ps). */
break;
}
destptr += ret;
len -= ret;
}
*srcp = src;
return destptr - dest;
}
else
{
/* Ignore dest and len, don't store *srcp at the end, and
don't clobber *ps. */
mbstate_t state = *ps;
size_t totalcount = 0;
for (;; src++)
{
wchar_t wc;
size_t ret;
wc = *src;
ret = wcrtomb (buf, wc, &state);
if (ret == (size_t)(-1))
goto bad_input2;
if (wc == 0)
{
/* Here mbsinit (&state). */
break;
}
totalcount += ret;
}
return totalcount;
}
bad_input:
*srcp = src;
bad_input2:
errno = EILSEQ;
return (size_t)(-1);
}
#endif /* HANDLE_MULTIBYTE */
+11 -28
View File
@@ -1335,12 +1335,13 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text)
memset (&ps2, 0, sizeof (mbstate_t));
}
#endif
if (_rl_completion_case_fold)
for (si = 0; (c1 = match_list[i][si]) && (c2 = match_list[i + 1][si]); si++)
{
for (si = 0;
(c1 = _rl_to_lower(match_list[i][si])) &&
(c2 = _rl_to_lower(match_list[i + 1][si]));
si++)
if (_rl_completion_case_fold)
{
c1 = _rl_to_lower (c1);
c2 = _rl_to_lower (c2);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
@@ -1352,35 +1353,17 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text)
break;
continue;
}
wc1 = towlower (wc1);
wc2 = towlower (wc2);
if (_rl_completion_case_fold)
{
wc1 = towlower (wc1);
wc2 = towlower (wc2);
}
if (wc1 != wc2)
break;
else if (v1 > 1)
si += v1 - 1;
}
else
#endif
if (c1 != c2)
break;
}
else
{
for (si = 0;
(c1 = match_list[i][si]) &&
(c2 = match_list[i + 1][si]);
si++)
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
mbstate_t ps_back;
ps_back = ps1;
if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
break;
else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
si += v - 1;
}
else
#endif
if (c1 != c2)
break;
+13 -12
View File
@@ -1,6 +1,6 @@
/* pathexp.c -- The shell interface to the globbing library. */
/* Copyright (C) 1995-2014 Free Software Foundation, Inc.
/* Copyright (C) 1995-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -58,9 +58,6 @@ int extended_glob = EXTGLOB_DEFAULT;
/* Control enabling special handling of `**' */
int glob_star = 0;
/* Do we handle backslashes in patterns the way Posix specifies? */
int posix_glob_backslash = 1;
/* Return nonzero if STRING has any unquoted special globbing chars in it.
This is supposed to be called when pathname expansion is performed, so
it implements the rules in Posix 2.13.3, specifically that an unquoted
@@ -107,8 +104,8 @@ unquoted_glob_pattern_p (string)
continue;
/* A pattern can't end with a backslash, but a backslash in the pattern
can be removed by the matching engine, so we have to run it through
globbing. */
can be special to the matching engine, so we note it in case we
need it later. */
case '\\':
if (*string != '\0' && *string != '/')
{
@@ -140,7 +137,11 @@ unquoted_glob_pattern_p (string)
#endif
}
return ((bsquote && posix_glob_backslash) ? 2 : 0);
#if 0
return (bsquote ? 2 : 0);
#else
return (0);
#endif
}
/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
@@ -343,7 +344,7 @@ quote_string_for_globbing (pathname, qflags)
else if (pathname[i] == '\\' && (qflags & QGLOB_REGEXP) == 0)
{
/* XXX - if not quoting regexp, use backslash as quote char. Should
we just pass it through without treating it as special? That is
We just pass it through without treating it as special? That is
what ksh93 seems to do. */
/* If we want to pass through backslash unaltered, comment out these
@@ -396,8 +397,9 @@ quote_globbing_chars (string)
/* Call the glob library to do globbing on PATHNAME. */
char **
shell_glob_filename (pathname)
shell_glob_filename (pathname, qflags)
const char *pathname;
int qflags;
{
#if defined (USE_POSIX_GLOB_LIBRARY)
register int i;
@@ -405,7 +407,7 @@ shell_glob_filename (pathname)
glob_t filenames;
int glob_flags;
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME|qflags);
filenames.gl_offs = 0;
@@ -452,8 +454,7 @@ shell_glob_filename (pathname)
noglob_dot_filenames = glob_dot_filenames == 0;
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
quoted_pattern = STREQ (pathname, temp) == 0;
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME|qflags);
gflags = glob_star ? GX_GLOBSTAR : 0;
results = glob_filename (temp, gflags);
free (temp);
+4 -3
View File
@@ -51,7 +51,6 @@ extern int glob_dot_filenames;
extern int extended_glob;
extern int glob_star;
extern int match_ignore_case; /* doesn't really belong here */
extern int posix_glob_backslash;
extern int unquoted_glob_pattern_p __P((char *));
@@ -70,8 +69,10 @@ extern char *quote_string_for_globbing __P((const char *, int));
extern int glob_char_p __P((const char *));
extern char *quote_globbing_chars __P((const char *));
/* Call the glob library to do globbing on PATHNAME. */
extern char **shell_glob_filename __P((const char *));
/* Call the glob library to do globbing on PATHNAME. FLAGS is additional
flags to pass to QUOTE_STRING_FOR_GLOBBING, mostly having to do with
whether or not we've already performed quote removal. */
extern char **shell_glob_filename __P((const char *, int));
/* Filename completion ignore. Used to implement the "fignore" facility of
tcsh, GLOBIGNORE (like ksh-93 FIGNORE), and EXECIGNORE.
+1 -1
View File
@@ -11251,7 +11251,7 @@ glob_expand_word_list (tlist, eflags)
if ((tlist->word->flags & W_NOGLOB) == 0 &&
unquoted_glob_pattern_p (tlist->word->word))
{
glob_array = shell_glob_filename (tlist->word->word);
glob_array = shell_glob_filename (tlist->word->word, QGLOB_CTLESC); /* XXX */
/* Handle error cases.
I don't think we should report errors like "No such file
+8 -8
View File
@@ -57,10 +57,10 @@ ok 3
ok 4
ok 5
argv[1] = <a\?>
a?
a\?
argv[1] = <a\?>
a?
aa
a\?
a\a
<define\/\
/>
./tmp/a/b/c ./tmp/a/b/c ./tmp/a/b/c
@@ -79,8 +79,8 @@ argv[1] = <./t\mp/a/*>
argv[1] = <./tmp/a/b/c>
argv[1] = <./tmp/a/>
argv[1] = <./tmp/a/b/>
argv[1] = <./tmp/a/>
argv[1] = <./tmp/a/b/>
argv[1] = <./t\mp/a/>
argv[1] = <./t\mp/a/b/>
argv[1] = <./tmp/a/*>
argv[1] = <./tmp/a/b/c>
argv[1] = <./tmp/a>
@@ -92,10 +92,10 @@ argv[1] = <\$foo>
argv[2] = <\$foo>
argv[1] = <mixed\$foo/>
<abcdefg>
<.>
<\.>
*abc.c
searchable/.
searchable/./.
searchable/\.
searchable/\./.
readable/\.
readable/\./.
searchable/\.
+2
View File
@@ -105,3 +105,5 @@ shopt -u -o
builtin printf -- "--\n"
shopt -p xyz1
shopt -o -p xyz1
${THIS_SH} ./shopt1.sub
+52
View File
@@ -0,0 +1,52 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# verify all shopt options are reset properly when the shell is reinitialized
: ${TMPDIR:=/var/tmp} ${THIS_SH:=$PWD/bash}
t1=$(mktemp)
t2=$(mktemp)
if [ ! -e "$t1" ] ; then
S1=$RANDOM
S2=$RANDOM
t1=$TMPDIR/s-$S1
t2=$TMPDIR/s-$S2
touch "$t1" "$t2"
fi
chmod +x "$t1" "$t2"
echo "shopt" > "$t1"
echo "#!${THIS_SH}" > "$t2"
echo "shopt" >> "$t2"
for o in $(compgen -A shopt)
do
case $o in
extdebug) ;;
*) shopt -s $o ;;
esac
done
diff <("$t1") <("$t2")
for o in $(compgen -A shopt)
do
shopt -u $o;
done
diff <("$t1") <("$t2")
rm "$t1" "$t2"
+6 -2
View File
@@ -1294,9 +1294,11 @@ assign_seconds (self, value, unused, key)
arrayind_t unused;
char *key;
{
struct timeval tv;
if (legal_number (value, &seconds_value_assigned) == 0)
seconds_value_assigned = 0;
shell_start_time = NOW;
gettimeofday (&tv, NULL);
shell_start_time = tv.tv_sec;
return (self);
}
@@ -1306,8 +1308,10 @@ get_seconds (var)
{
time_t time_since_start;
char *p;
struct timeval tv;
time_since_start = NOW - shell_start_time;
gettimeofday(&tv, NULL);
time_since_start = tv.tv_sec - shell_start_time;
p = itos(seconds_value_assigned + time_since_start);
FREE (value_cell (var));