commit bash-snap-20170620 snapshot

This commit is contained in:
Chet Ramey
2017-06-20 10:38:13 -04:00
parent 6374eecf23
commit d7d836dfc5
16 changed files with 195 additions and 34 deletions
+67
View File
@@ -14102,3 +14102,70 @@ parse.y
lib/readline/display.c
- update_line: when wrapping multibyte characters, make sure we deal
with WCWIDTH returning -1. Fixes a fuzzing bug
6/17
----
execute_cmd.c
- execute_coproc: make sure `invert' is set before trying to use it
when returning failure on invalid coproc name. Report and fix from
Eduardo Bustamante <dualbus@gmail.com>
- execute_command_internal: make sure execute_coproc sets
last_command_exit_value if it returns failure, so an invalid name
can set $? = 1. Report and fix from Eduardo Bustamante
<dualbus@gmail.com>
lib/readline/display.c
- update_line: make sure all references to `wrapped_line' are wrapped
with #ifdef HANDLE_MULTIBYTE. Report and fix from Eduardo Bustamante
<dualbus@gmail.com>
lib/readline/vi_mode.c
- _rl_vi_change_char: don't use rl_point++ when you mean to move
forward a character; use _rl_vi_append_forward to account for
multibyte characters and take vi end of line handling into account
- _rl_vi_last_replacement: now an array of chars whether we are
using multibyte chars or not. If we're not, the character we read
to use as the replacement is saved as the first element of the array
- rl_vi_change_char,_rl_vi_callback_change_char: changes to deal with
_rl_vi_last_replacement being an array. Fixes bug reported by
Eduardo Bustamante <dualbus@gmail.com>
lib/readline/mbutil.c
- _rl_get_char_len: look at at most MB_CUR_MAX characters, but maybe
fewer if the length of the string is less
builtins/bind.def
- unbind_keyseq: new function for the -r option; checks whether the
key sequence is actually bound before trying to bind it to NULL.
Partial fix for https://savannah.gnu.org/support/?109329
parse.y
- augment `error yacc_EOF' production to call YYABORT in non-interactive
shells or calls to parse_and_execute (eval, command substitution,
etc.) Fixes bug reported by Martijn Dekker <martijn@inlv.org>
6/19
----
bashline.c
- edit_and_execute_command: don't add rl_line_buffer to the history
list if it's empty; consistent with how other code treats an empty
line
execute_cmd.c
- execute_builtin: make sure to preserve the temporary env across the
execution of the `read' builtin or `fc' builtin if HISTORY is
defined, in case `read -e' calls edit-and-execute-command. Should
have no side effects. Reported by Eduardo Bustamante
<dualbus@gmail.com>
general.c
- line_isblank: new function: returns true if passed string is composed
entirely of blanks
general.h
- line_isblank: new extern declaration
parse.y
- history_delimiting_chars: return "" for a blank line, since there's
nothing to delimit with `;'
+5 -2
View File
@@ -959,8 +959,11 @@ edit_and_execute_command (count, c, editing_mode, edit_command)
/* This breaks down when using command-oriented history and are not
finished with the command, so we should not ignore the last command */
using_history ();
current_command_line_count++; /* for rl_newline above */
bash_add_history (rl_line_buffer);
if (rl_line_buffer[0])
{
current_command_line_count++; /* for rl_newline above */
bash_add_history (rl_line_buffer);
}
current_command_line_count = 0; /* for dummy history entry */
bash_add_history ("");
history_lines_this_session++;
+37 -5
View File
@@ -88,6 +88,7 @@ extern int errno;
static int query_bindings __P((char *));
static int unbind_command __P((char *));
static int unbind_keyseq __P((char *));
#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0)
@@ -264,11 +265,8 @@ bind_builtin (list)
if ((flags & RFLAG) && remove_seq)
{
if (rl_bind_keyseq (remove_seq, (rl_command_func_t *)NULL) != 0)
{
builtin_error (_("`%s': cannot unbind"), remove_seq);
BIND_RETURN (EXECUTION_FAILURE);
}
opt = unbind_keyseq (remove_seq);
BIND_RETURN (opt);
}
if (flags & XFLAG)
@@ -341,4 +339,38 @@ unbind_command (name)
rl_unbind_function_in_map (function, rl_get_keymap ());
return EXECUTION_SUCCESS;
}
static int
unbind_keyseq (seq)
char *seq;
{
char *kseq;
int kslen;
kseq = (char *)xmalloc ((2 * strlen (seq)) + 1);
if (rl_translate_keyseq (seq, kseq, &kslen))
{
free (kseq);
builtin_error (_("`%s': cannot unbind"), seq);
return EXECUTION_FAILURE;
}
if (rl_function_of_keyseq (kseq, (Keymap)0, (int *)0) == 0)
{
free (kseq);
return (EXECUTION_SUCCESS);
}
/* I wish this didn't have to translate the key sequence again, but readline
doesn't have a binding function that takes a translated key sequence as
an argument. */
if (rl_bind_keyseq (seq, (rl_command_func_t *)NULL) != 0)
{
free (kseq);
builtin_error (_("`%s': cannot unbind"), seq);
return (EXECUTION_FAILURE);
}
free (kseq);
return (EXECUTION_SUCCESS);
}
#endif /* READLINE */
+1 -1
View File
@@ -39,7 +39,7 @@ Options:
variable ARRAY, starting at zero
-d delim continue until the first character of DELIM is read, rather
than newline
-e use Readline to obtain the line in an interactive shell
-e use Readline to obtain the line
-i text use TEXT as the initial text for Readline
-n nchars return after reading NCHARS characters rather than waiting
for a newline, but honor a delimiter if fewer than
+1 -1
View File
@@ -9041,7 +9041,7 @@ is coming from a terminal,
.B READLINE
above) is used to obtain the line.
Readline uses the current (or default, if line editing was not previously
active) editing settings.
active) editing settings, but uses Readline's default filename completion.
.TP
.B \-i \fItext\fP
If
+1 -1
View File
@@ -4493,7 +4493,7 @@ when it reads a NUL character.
@item -e
Readline (@pxref{Command Line Editing}) is used to obtain the line.
Readline uses the current (or default, if line editing was not previously
active) editing settings.
active) editing settings, but uses Readline's default filename completion.
@item -i @var{text}
If Readline is being used to read the line, @var{text} is placed into
+11 -3
View File
@@ -32,29 +32,37 @@ the canonical example. There is no real `builtin writers' programming
guide'. The file template.c provides a template to use for creating
new loadable builtins.
The file "Makefile.inc" is created using the same values that configure
writes into Makefile.in, and is installed in the same directory as the
rest of the example builtins. It's intended to be a start at something
that can be modified or included to help you build your own loadables
without having to search for the right CFLAGS and LDFLAGS.
basename.c Return non-directory portion of pathname.
cat.c cat(1) replacement with no options - the way cat was intended.
dirname.c Return directory portion of pathname.
fdflags.c Change the flag associated with one of bash's open file desriptors.
finfo.c Print file info.
head.c Copy first part of files.
hello.c Obligatory "Hello World" / sample loadable.
id.c POSIX.2 user identity.
ln.c Make links.
loadables.h Start at a file loadable builtins can include for shell definitions
loadables.h File loadable builtins can include for shell definitions.
logname.c Print login name of current user.
Makefile.in Simple makefile for the sample loadable builtins.
mkdir.c Make directories.
mypid.c Add $MYPID variable, demonstrate use of unload hook function
mypid.c Add $MYPID variable, demonstrate use of unload hook functio.n
necho.c echo without options or argument interpretation.
pathchk.c Check pathnames for validity and portability.
print.c Loadable ksh-93 style print builtin.
printenv.c Minimal builtin clone of BSD printenv(1).
push.c Anyone remember TOPS-20?
README README
realpath.c Canonicalize pathnames, resolving symlinks.
rm.c Remove files and directories.
rmdir.c Remove directory.
setpgid.c Set a process's pgrp; example of how to wrap a system call.
sleep.c sleep for fractions of a second.
stat.c populate an associative array with information about a file
strftime.c Loadable builtin interface to strftime(3).
sync.c Sync the disks by forcing pending filesystem writes to complete.
tee.c Duplicate standard input.
+4 -1
View File
@@ -88,13 +88,16 @@ WORD_LIST *list;
break;
default:
builtin_usage();
return (EX_USAGE);
}
}
list = loptend;
if (list == 0)
if (list == 0) {
builtin_usage();
return (EX_USAGE);
}
for (es = EXECUTION_SUCCESS; list; list = list->next) {
p = list->word->word;
+7 -2
View File
@@ -598,7 +598,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
#if defined (COPROCESS_SUPPORT)
if (command->type == cm_coproc)
return (execute_coproc (command, pipe_in, pipe_out, fds_to_close));
return (last_command_exit_value = execute_coproc (command, pipe_in, pipe_out, fds_to_close));
#endif
user_subshell = command->type == cm_subshell || ((command->flags & CMD_WANT_SUBSHELL) != 0);
@@ -2298,6 +2298,8 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
coproc_init (&sh_coproc);
#endif
invert = (command->flags & CMD_INVERT_RETURN) != 0;
/* XXX - expand coproc name without splitting -- bash-5.0 */
/* could make this dependent on a shopt option */
name = expand_string_unsplit_to_string (command->value.Coproc->name, 0);
@@ -2313,7 +2315,6 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
command->value.Coproc->name = name;
}
invert = (command->flags & CMD_INVERT_RETURN) != 0;
command_string_index = 0;
tcmd = make_command_string (command);
@@ -4554,6 +4555,10 @@ execute_builtin (builtin, words, flags, subshell)
`mapfile' is a special case because it uses evalstring (same as
eval or source) to run its callbacks. */
isbltinenv = (builtin == source_builtin || builtin == eval_builtin || builtin == unset_builtin || builtin == mapfile_builtin);
#if defined (HISTORY) && defined (READLINE)
if (builtin == fc_builtin || builtin == read_builtin)
isbltinenv = 1;
#endif
if (isbltinenv)
{
+14
View File
@@ -402,6 +402,20 @@ assignment (string, flags)
return (0);
}
int
line_isblank (line)
const char *line;
{
register int i;
if (line == 0)
return 0; /* XXX */
for (i = 0; line[i]; i++)
if (isblank ((unsigned char)line[i]) == 0)
break;
return (line[i] == '\0');
}
/* **************************************************************** */
/* */
/* Functions to manage files and file descriptors */
+1
View File
@@ -292,6 +292,7 @@ extern int check_identifier __P((WORD_DESC *, int));
extern int valid_nameref_value __P((const char *, int));
extern int check_selfref __P((const char *, char *, int));
extern int legal_alias_name __P((const char *, int));
extern int line_isblank __P((const char *));
extern int assignment __P((const char *, int));
extern int sh_unset_nodelay_mode __P((int));
+2
View File
@@ -2128,6 +2128,7 @@ dumb_update:
}
#if 1
#ifdef HANDLE_MULTIBYTE
/* If we write a non-space into the last screen column,
remove the note that we added a space to compensate for
a multibyte double-width character that didn't fit, since
@@ -2137,6 +2138,7 @@ dumb_update:
line_state_invisible->wrapped_line[current_line+1] &&
nfd[bytes_to_insert-1] != ' ')
line_state_invisible->wrapped_line[current_line+1] = 0;
#endif
#endif
}
else
+3 -2
View File
@@ -655,7 +655,7 @@ _rl_read_mbchar (char *mbchar, int size)
int
_rl_read_mbstring (int first, char *mb, int mlen)
{
int i, c;
int i, c, n;
mbstate_t ps;
c = first;
@@ -664,7 +664,8 @@ _rl_read_mbstring (int first, char *mb, int mlen)
{
mb[i] = (char)c;
memset (&ps, 0, sizeof (mbstate_t));
if (_rl_get_char_len (mb, &ps) == -2)
n = _rl_get_char_len (mb, &ps);
if (n == -2)
{
/* Read more for multibyte character */
RL_SETSTATE (RL_STATE_MOREINPUT);
+6 -2
View File
@@ -223,9 +223,13 @@ _rl_find_prev_mbchar_internal (char *string, int seed, int find_non_zero)
int
_rl_get_char_len (char *src, mbstate_t *ps)
{
size_t tmp;
size_t tmp, l;
int mb_cur_max;
tmp = mbrlen((const char *)src, MB_CUR_MAX, ps);
/* Look at no more than MB_CUR_MAX characters */
l = (size_t)strlen (src);
mb_cur_max = MB_CUR_MAX;
tmp = mbrlen((const char *)src, (l < mb_cur_max) ? l : mb_cur_max, ps);
if (tmp == (size_t)(-2))
{
/* shorted to compose multibyte char */
+23 -13
View File
@@ -101,7 +101,7 @@ static int _rl_vi_last_search_mblen;
#else
static int _rl_vi_last_search_char;
#endif
static int _rl_vi_last_replacement;
static char _rl_vi_last_replacement[MB_LEN_MAX+1]; /* reserve for trailing NULL */
static int _rl_vi_last_key_before_insert;
@@ -646,11 +646,7 @@ _rl_vi_append_forward (int key)
else
{
point = rl_point;
#if 0
rl_forward_char (1, key);
#else
rl_point = _rl_forward_char_internal (1);
#endif
if (point == rl_point)
rl_point = rl_end;
}
@@ -1889,7 +1885,7 @@ _rl_vi_change_char (int count, int c, char *mb)
p = rl_point;
rl_vi_delete (1, c);
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++;
_rl_vi_append_forward (c);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (mb);
@@ -1931,9 +1927,15 @@ static int
_rl_vi_callback_change_char (_rl_callback_generic_arg *data)
{
int c;
char mb[MB_LEN_MAX];
char mb[MB_LEN_MAX+1];
_rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
#if defined (HANDLE_MULTIBYTE)
strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
#else
_rl_vi_last_replacement[0] = c;
#endif
_rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* XXX */
if (c < 0)
return -1;
@@ -1949,13 +1951,13 @@ int
rl_vi_change_char (int count, int key)
{
int c;
char mb[MB_LEN_MAX];
char mb[MB_LEN_MAX+1];
if (_rl_vi_redoing)
{
c = _rl_vi_last_replacement;
mb[0] = c;
mb[1] = '\0';
strncpy (mb, _rl_vi_last_replacement, MB_LEN_MAX);
c = (unsigned char)_rl_vi_last_replacement[0]; /* XXX */
mb[MB_LEN_MAX] = '\0';
}
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
@@ -1966,7 +1968,15 @@ rl_vi_change_char (int count, int key)
}
#endif
else
_rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
{
c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
#ifdef HANDLE_MULTIBYTE
strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
#else
_rl_vi_last_replacement[0] = c;
#endif
_rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* just in case */
}
if (c < 0)
return -1;
+12 -1
View File
@@ -416,8 +416,16 @@ inputunit: simple_list simple_list_terminator
/* EOF after an error. Do ignoreeof or not. Really
only interesting in non-interactive shells */
global_command = (COMMAND *)NULL;
last_command_exit_value = 1;
handle_eof_input_unit ();
YYACCEPT;
if (interactive && parse_and_execute_level == 0)
{
YYACCEPT;
}
else
{
YYABORT;
}
}
| yacc_EOF
{
@@ -5457,6 +5465,9 @@ history_delimiting_chars (line)
return (" ");
}
if (line_isblank (line))
return ("");
return ("; ");
}
#endif /* HISTORY */