fix for completing quoted filenames with show-all-if-ambiguous set; avoid signed int overflow in intrand32

This commit is contained in:
Chet Ramey
2023-01-10 10:23:14 -05:00
parent 8fd8cd8f7b
commit 0647e53bd1
8 changed files with 83 additions and 18 deletions
+27
View File
@@ -4978,3 +4978,30 @@ lib/readline/{vi_mode.c,histfile.c,funmap.c,complete.c,display.c,bind.c,isearch.
lib/tilde/tilde.c
- final code cleanups for ANSI C and lint/ubsan/asan runs
1/7
---
lib/readline/complete.c
- rl_complete_internal: when computing nontrivial_lcd and the length
of the text from the line buffer, dequote the text from the line
buffer before comparing it against the common prefix of the matches
(matches[0]), so we don't get spurious mismatches if the quoted text
from the line is longer than the unquoted match. Report from
Martin Castillo <castilma@uni-bremen.de>
input.[ch]
- get_buffered_stream(fd): new function, return the BUFFERED_STREAM *
corresponding to file descriptor FD, if it exists
1/8
---
parse.y
- shell_getc: if yy_getc returns EOF but the buffered stream input
indicates an error state, set shell_input_line_terminator to
READERR. Currently treated the same as EOF.
1/10
----
lib/sh/random.c
- intrand32: use % operator instead of (mathematically equivalent)
subtraction and multiplication, which can cause signed 32-bit
overflow. Report from Sam James <sam@gentoo.org>
+1 -1
View File
@@ -10094,7 +10094,7 @@ arithmetic \fBfor\fP command, display the expanded value of
.SM
.BR PS4 ,
followed by the command and its expanded arguments
or associated word list.
or associated word list, to standard error.
.TP 8
.B \-B
The shell performs brace expansion (see
+3 -3
View File
@@ -5455,9 +5455,9 @@ Print shell input lines as they are read.
@item -x
Print a trace of simple commands, @code{for} commands, @code{case}
commands, @code{select} commands, and arithmetic @code{for} commands
and their arguments or associated word lists after they are
expanded and before they are executed. The value of the @env{PS4}
variable is expanded and the resultant value is printed before
and their arguments or associated word lists to standard error
after they are expanded and before they are executed.
The shell prints the expanded value of the @env{PS4} variable before
the command and its expanded arguments.
@item -B
+7
View File
@@ -464,6 +464,13 @@ set_buffered_stream (int fd, BUFFERED_STREAM *bp)
return ret;
}
/* Return the BUFFERED_STREAM associated with FD, if any. */
BUFFERED_STREAM *
get_buffered_stream (int fd)
{
return (buffers && fd < nbuffers) ? buffers[fd] : (BUFFERED_STREAM *)0;
}
/* Read a buffer full of characters from BP, a buffered stream. */
static int
b_fill_buffer (BUFFERED_STREAM *bp)
+7 -9
View File
@@ -23,15 +23,6 @@
#include "stdc.h"
/* Function pointers can be declared as (Function *)foo. */
#if !defined (_FUNCTION_DEF)
# define _FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
typedef char *CPFunction (); /* no longer used */
typedef char **CPPFunction (); /* no longer used */
#endif /* _FUNCTION_DEF */
typedef int sh_cget_func_t (void); /* sh_ivoidfunc_t */
typedef int sh_cunget_func_t (int); /* sh_intfunc_t */
@@ -70,6 +61,12 @@ extern BUFFERED_STREAM **buffers;
extern int default_buffered_input;
extern int bash_input_fd_changed;
#undef beof
#undef berror
#define beof(bp) (((bp)->b_flag & B_EOF) != 0)
#define berror(bp) (((bp)->b_flag & B_ERROR) != 0)
#endif /* BUFFERED_INPUT */
typedef union {
@@ -122,6 +119,7 @@ extern int check_bash_input (int);
extern int duplicate_buffered_stream (int, int);
extern BUFFERED_STREAM *fd_to_buffered_stream (int);
extern BUFFERED_STREAM *set_buffered_stream (int, BUFFERED_STREAM *);
extern BUFFERED_STREAM *get_buffered_stream (int);
extern BUFFERED_STREAM *open_buffered_stream (char *);
extern void free_buffered_stream (BUFFERED_STREAM *);
extern int close_buffered_stream (BUFFERED_STREAM *);
+17 -1
View File
@@ -2037,9 +2037,25 @@ rl_complete_internal (int what_to_do)
text = rl_copy_text (start, end);
matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
/* If TEXT contains quote characters, it will be dequoted as part of
generating the matches, and the matches will not contain any quote
characters. We need to dequote TEXT before performing the comparison.
Since compare_match performs the dequoting, and we only want to do it
once, we don't call compare_matches after dequoting TEXT; we call
strcmp directly. */
/* nontrivial_lcd is set if the common prefix adds something to the word
being completed. */
nontrivial_lcd = matches && compare_match (text, matches[0]) != 0;
if (rl_filename_completion_desired && rl_filename_quoting_desired &&
rl_completion_found_quote && rl_filename_dequoting_function)
{
char *t;
t = (*rl_filename_dequoting_function) (text, rl_completion_quote_character);
xfree (text);
text = t;
nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
}
else
nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
if (what_to_do == '!' || what_to_do == '@')
tlen = strlen (text);
xfree (text);
+2 -2
View File
@@ -1,6 +1,6 @@
/* random.c -- Functions for managing 16-bit and 32-bit random numbers. */
/* Copyright (C) 2020,2022 Free Software Foundation, Inc.
/* Copyright (C) 2020,2022,2023 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -75,7 +75,7 @@ intrand32 (u_bits32_t last)
/* Can't seed with 0. */
ret = (last == 0) ? 123459876 : last;
h = ret / 127773;
l = ret - (127773 * h);
l = ret % 127773;
t = 16807 * l - 2836 * h;
ret = (t < 0) ? t + 0x7fffffff : t;
+19 -2
View File
@@ -97,6 +97,10 @@ typedef void *alias_t;
#define END_ALIAS -2
#ifndef READERR
# define READERR -2
#endif
#ifdef DEBUG
# define YYDEBUG 1
#else
@@ -2433,6 +2437,15 @@ shell_getc (int remove_quoted_newline)
if (i == 0)
shell_input_line_terminator = EOF;
#if defined (BUFFERED_INPUT)
if (i == 0)
{
BUFFERED_STREAM *bp;
bp = get_buffered_stream (default_buffered_input);
if (bp && berror (bp))
shell_input_line_terminator = READERR;
}
#endif
shell_input_line[i] = '\0';
break;
@@ -2525,7 +2538,8 @@ shell_getc (int remove_quoted_newline)
reason for the test against shell_eof_token, which is set to a
right paren when parsing the contents of command substitutions. */
if (echo_input_at_read && (shell_input_line[0] ||
shell_input_line_terminator != EOF) &&
(shell_input_line_terminator != EOF &&
shell_input_line_terminator != READERR)) &&
shell_eof_token == 0)
fprintf (stderr, "%s\n", shell_input_line);
}
@@ -2540,7 +2554,7 @@ shell_getc (int remove_quoted_newline)
/* Add the newline to the end of this string, iff the string does
not already end in an EOF character. */
if (shell_input_line_terminator != EOF)
if (shell_input_line_terminator != EOF && shell_input_line_terminator != READERR)
{
if (shell_input_line_size < SIZE_MAX-3 && (shell_input_line_len+3 > shell_input_line_size))
shell_input_line = (char *)xrealloc (shell_input_line,
@@ -2676,6 +2690,9 @@ pop_alias:
if (uc == 0 && shell_input_line_terminator == EOF)
return ((shell_input_line_index != 0) ? '\n' : EOF);
else if (uc == 0 && shell_input_line_terminator == READERR)
/* Treat read errors like EOF here. */
return ((shell_input_line_index != 0) ? '\n' : EOF);
#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
/* We already know that we are not parsing an alias expansion because of the