From: Chet Ramey Date: Mon, 19 May 2025 13:10:57 +0000 (-0400) Subject: some fixes for static analysis findings; fix for brace expansion being too greedy... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=870ad4c92b771aafe5b444792a8fa904b2d4a418;p=thirdparty%2Fbash.git some fixes for static analysis findings; fix for brace expansion being too greedy checking sequence expressions; fix for strip targets when cross-compiling --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 58c4975a..33a9a12a 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -11210,3 +11210,42 @@ builtins/read.def use zungetc to push back that character and everything we read after it so subsequent buffered (zread) or unbuffered (read) reads will return them + + 5/2 + --- +lib/readline/display.c,lib/readline/histexpand.c,lib/readline/history.c, +lib/readline/input.c,lib/readline/search.c,lib/readline/shell.c, +lib/readline/util.c,lib/readline/readline.c,lib/readline/histfile.c + - fixes for issues (unused variables, etc.) uncovered by static + analysis + All from a report by Siteshwar Vashisht + + 5/16 + ---- +lib/readline/terminal.c + - NEED_EXTERN_PC: add __gnu_hurd__ to the systems that require this + if not using ncurses; rework the structure of the defines + Report from Collin Funk + +braces.c + - brace_gobbler: don't mark an expression as BRACE_SEQ if we've + already seen a comma and marked it as BRACE_COMMA, so we treat + it as a comma brace expansion. + From a report by Sam James + +support/install-sh + - new version from coreutils-git (2024-12-03.03); renamed from install.sh + +aclocal.m4 + - AM_PROG_INSTALL_SH, AM_PROG_INSTALL_STRIP: added from automake + +configure.ac + - call AM_PROG_INSTALL_SH, AM_PROG_INSTALL_STRIP + +Makefile.in + - STRIP: let configure substitute it from AC_CHECK_TOOL result + - INSTALL_STRIP_PROGRAM: let configure substitute it from + AM_PROG_INSTALL_STRIP + - install-strip: change to set INSTALL_PROGRAM=${INSTALL_STRIP_PROGRAM} + to avoid hard-coding `-s' in the recipe + All from a report by NR diff --git a/MANIFEST b/MANIFEST index e6036372..f294d0e0 100644 --- a/MANIFEST +++ b/MANIFEST @@ -741,7 +741,7 @@ support/zecho.c f support/xcase.c f support/SYMLINKS f support/fixlinks f 755 -support/install.sh f 755 +support/install-sh f 755 support/texi2dvi f 755 support/texi2html f 755 #support/xenix-link.sh f 755 diff --git a/Makefile.in b/Makefile.in index 3e8e8658..c4a882f7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile for bash-5.3, version 5.8 +# Makefile for bash-5.3, version 5.10 # # Copyright (C) 1996-2025 Free Software Foundation, Inc. @@ -79,15 +79,18 @@ AR = @AR@ ARFLAGS = @ARFLAGS@ RANLIB = @RANLIB@ SIZE = @SIZE@ -STRIP = strip +STRIP = @STRIP@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_DATA = @INSTALL_DATA@ INSTALLMODE= -m 0755 INSTALLMODE2 = -m 0555 +install_sh = @install_sh@ + CTAGS = ctags CTAGSFLAGS = -x ETAGS = etags @@ -923,7 +926,7 @@ install: .made installdirs -( cd $(LOADABLES_DIR) && $(MAKE) $(BASH_MAKEFLAGS) DESTDIR=$(DESTDIR) $@ ) install-strip: - $(MAKE) $(BASH_MAKEFLAGS) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \ + $(MAKE) $(BASH_MAKEFLAGS) INSTALL_PROGRAM='$(INSTALL_STRIP_PROGRAM)' \ prefix=${prefix} exec_prefix=${exec_prefix} \ DESTDIR=$(DESTDIR) install diff --git a/aclocal.m4 b/aclocal.m4 index 89e3b069..ae2d8aec 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -2262,3 +2262,46 @@ if test "$bash_cv_func_strchrnul_works" = "no"; then AC_LIBOBJ([strchrnul]) fi ]) + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +#if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +#fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) diff --git a/braces.c b/braces.c index 49bd770e..fb9230e0 100644 --- a/braces.c +++ b/braces.c @@ -783,8 +783,9 @@ comsub: commas++; } else if (satisfy == '}' && STREQN (text+i, BRACE_SEQ_SPECIFIER, 2) && - text[i+2] != satisfy && level == 0) + text[i+2] != satisfy && level == 0 && btype == BRACE_NONE) { + /* The check against BRACE_NONE gives the comma higher precedence */ btype = BRACE_SEQ; commas++; } diff --git a/configure b/configure index b7da824d..3156225f 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac for Bash 5.3, version 5.078. +# From configure.ac for Bash 5.3, version 5.079. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.72 for bash 5.3-rc1. # @@ -740,6 +740,9 @@ SED MKDIR_P SIZE MAKE_SHELL +INSTALL_STRIP_PROGRAM +STRIP +install_sh SET_MAKE YFLAGS YACC @@ -6407,6 +6410,132 @@ printf "%s\n" "no" >&6; } fi + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +#if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_STRIP+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +printf "%s\n" "$STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_STRIP+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +printf "%s\n" "$ac_ct_STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +#fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + + case "$ac_cv_prog_YACC" in *bison*) ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: bison not available; needed to process parse.y" >&5 @@ -9228,8 +9357,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$save_LIBS test $gl_pthread_api = yes && break done - echo "$as_me:9231: gl_pthread_api=$gl_pthread_api" >&5 - echo "$as_me:9232: LIBPTHREAD=$LIBPTHREAD" >&5 + echo "$as_me:9360: gl_pthread_api=$gl_pthread_api" >&5 + echo "$as_me:9361: LIBPTHREAD=$LIBPTHREAD" >&5 gl_pthread_in_glibc=no # On Linux with glibc >= 2.34, libc contains the fully functional @@ -9255,7 +9384,7 @@ rm -rf conftest* ;; esac - echo "$as_me:9258: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5 + echo "$as_me:9387: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5 # Test for libpthread by looking for pthread_kill. (Not pthread_self, # since it is defined as a macro on OSF/1.) @@ -9433,7 +9562,7 @@ fi fi fi - echo "$as_me:9436: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5 + echo "$as_me:9565: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5 printf %s "checking whether POSIX threads API is available... " >&6; } @@ -9680,8 +9809,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$save_LIBS test $gl_pthread_api = yes && break done - echo "$as_me:9683: gl_pthread_api=$gl_pthread_api" >&5 - echo "$as_me:9684: LIBPTHREAD=$LIBPTHREAD" >&5 + echo "$as_me:9812: gl_pthread_api=$gl_pthread_api" >&5 + echo "$as_me:9813: LIBPTHREAD=$LIBPTHREAD" >&5 gl_pthread_in_glibc=no # On Linux with glibc >= 2.34, libc contains the fully functional @@ -9707,7 +9836,7 @@ rm -rf conftest* ;; esac - echo "$as_me:9710: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5 + echo "$as_me:9839: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5 # Test for libpthread by looking for pthread_kill. (Not pthread_self, # since it is defined as a macro on OSF/1.) @@ -9885,7 +10014,7 @@ fi fi fi - echo "$as_me:9888: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5 + echo "$as_me:10017: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5 printf %s "checking whether POSIX threads API is available... " >&6; } @@ -10655,7 +10784,6 @@ with_gnu_ld=$acl_cv_prog_gnu_ld - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 printf %s "checking for shared library run path origin... " >&6; } if test ${acl_cv_rpath+y} diff --git a/configure.ac b/configure.ac index fdf542fa..85926929 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script. # You should have received a copy of the GNU General Public License # along with this program. If not, see . -AC_REVISION([for Bash 5.3, version 5.078])dnl +AC_REVISION([for Bash 5.3, version 5.079])dnl define(bashvers, 5.3) define(relstatus, rc1) @@ -32,7 +32,7 @@ dnl make sure we are using a recent autoconf version AC_PREREQ(2.69) AC_CONFIG_SRCDIR(shell.h) -dnl where to find install.sh, config.sub, and config.guess +dnl where to find install-sh, config.sub, and config.guess AC_CONFIG_AUX_DIR(./support) AC_CONFIG_HEADERS(config.h buildconf.h) @@ -695,6 +695,9 @@ AC_PROG_RANLIB AC_PROG_YACC AC_PROG_MAKE_SET +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP + case "$ac_cv_prog_YACC" in *bison*) ;; *) AC_MSG_WARN([bison not available; needed to process parse.y]) ;; diff --git a/doc/bash.html b/doc/bash.html index 3a13c3d2..07c85444 100644 --- a/doc/bash.html +++ b/doc/bash.html @@ -16930,7 +16930,7 @@ Array variables may not (yet) be exported.
BUGS

-This document was created by man2html from /usr/local/src/bash/bash-20250418/doc/bash.1.
-Time: 22 April 2025 10:00:07 EDT +This document was created by man2html from /usr/local/src/bash/bash-20250502/doc/bash.1.
+Time: 04 May 2025 17:25:09 EDT diff --git a/lib/readline/display.c b/lib/readline/display.c index 021dc3fc..9aa8c7b5 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -809,7 +809,7 @@ rl_redisplay (void) { int in, out, c, linenum, cursor_linenum; int inv_botlin, lb_botlin, lb_linenum, o_cpos; - int newlines, lpos, temp, num, prompt_lines_estimate; + int newlines, lpos, temp, num; char *prompt_this_line; char cur_face; int hl_begin, hl_end; @@ -1014,9 +1014,6 @@ rl_redisplay (void) on the first and last prompt lines; change that to use local_prompt_invis_chars */ - /* This is zero-based, used to set the newlines */ - prompt_lines_estimate = lpos / _rl_screenwidth; - /* what if lpos is already >= _rl_screenwidth before we start drawing the contents of the command line? */ if (lpos >= _rl_screenwidth) @@ -1908,7 +1905,6 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l if (newwidth > 0) { int i, j; - char *optr; puts_face (new, new_face, newbytes); _rl_last_c_pos = newwidth; diff --git a/lib/readline/histexpand.c b/lib/readline/histexpand.c index fc0008e8..085b4541 100644 --- a/lib/readline/histexpand.c +++ b/lib/readline/histexpand.c @@ -679,7 +679,7 @@ history_expand_internal (const char *string, int start, int qc, int *end_index_p case 's': { char *new_event; - int delimiter, failed, si, l_temp, ws, we; + int delimiter, failed, si, l_temp, we; if (c == 's') { @@ -778,7 +778,6 @@ history_expand_internal (const char *string, int start, int qc, int *end_index_p { for (; temp[si] && fielddelim (temp[si]); si++) ; - ws = si; we = history_tokenize_word (temp, si); } diff --git a/lib/readline/histfile.c b/lib/readline/histfile.c index 56490508..11bdd84b 100644 --- a/lib/readline/histfile.c +++ b/lib/readline/histfile.c @@ -182,6 +182,7 @@ history_filename (const char *filename) return (return_val); } +#if defined (DEBUG) static char * history_backupfile (const char *filename) { @@ -208,6 +209,7 @@ history_backupfile (const char *filename) ret[len+1] = '\0'; return ret; } +#endif static char * history_tempfile (const char *filename) @@ -485,6 +487,7 @@ history_rename (const char *old, const char *new) #endif } +#if defined (DEBUG) /* Save FILENAME to BACK, handling case where FILENAME is a symlink (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */ static int @@ -503,6 +506,7 @@ histfile_backup (const char *filename, const char *back) #endif return (history_rename (filename, back)); } +#endif /* Restore ORIG from BACKUP handling case where ORIG is a symlink (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */ @@ -723,13 +727,13 @@ static int history_write_slow (int fd, HIST_ENTRY **the_history, int nelements, int overwrite) { FILE *fp; - int i, j, e; + int i, e; fp = fdopen (fd, overwrite ? "w" : "a"); if (fp == 0) return -1; - for (j = 0, i = history_length - nelements; i < history_length; i++) + for (i = history_length - nelements; i < history_length; i++) { if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0]) fprintf (fp, "%s\n", the_history[i]->timestamp); diff --git a/lib/readline/history.c b/lib/readline/history.c index aade5e33..2d0400b7 100644 --- a/lib/readline/history.c +++ b/lib/readline/history.c @@ -202,7 +202,7 @@ using_history (void) int history_total_bytes (void) { - register int i, result; + int i, result; for (i = result = 0; the_history && the_history[i]; i++) result += HISTENT_BYTES (the_history[i]); @@ -545,7 +545,7 @@ void _hs_replace_history_data (int which, histdata_t *old, histdata_t *new) { HIST_ENTRY *entry; - register int i, last; + int i, last; if (which < -2 || which >= history_length || history_length == 0 || the_history == 0) return; @@ -581,7 +581,7 @@ _hs_replace_history_data (int which, histdata_t *old, histdata_t *new) int _hs_search_history_data (histdata_t *needle) { - register int i; + int i; HIST_ENTRY *entry; if (history_length == 0 || the_history == 0) @@ -605,10 +605,11 @@ HIST_ENTRY * remove_history (int which) { HIST_ENTRY *return_value; - register int i; #if 1 int nentries; HIST_ENTRY **start, **end; +#else + int i; #endif if (which < 0 || which >= history_length || history_length == 0 || the_history == 0) diff --git a/lib/readline/input.c b/lib/readline/input.c index 4eefb274..e6a39e26 100644 --- a/lib/readline/input.c +++ b/lib/readline/input.c @@ -921,7 +921,7 @@ rl_getc (FILE *stream) /* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */ -handle_error: + /* Handle errors here. */ osig = _rl_caught_signal; ostate = rl_readline_state; diff --git a/lib/readline/readline.c b/lib/readline/readline.c index 03ab24ab..e77f89d9 100644 --- a/lib/readline/readline.c +++ b/lib/readline/readline.c @@ -1366,6 +1366,7 @@ readline_default_bindings (void) rl_tty_set_default_bindings (_rl_keymap); } +#if defined (DEBUG) /* Reset the default bindings for the terminal special characters we're interested in back to rl_insert and read the new ones. */ static void @@ -1377,6 +1378,7 @@ reset_default_bindings (void) rl_tty_set_default_bindings (_rl_keymap); } } +#endif /* Bind some common arrow key sequences in MAP. */ static void diff --git a/lib/readline/search.c b/lib/readline/search.c index 80361757..a7ab9479 100644 --- a/lib/readline/search.c +++ b/lib/readline/search.c @@ -590,7 +590,6 @@ rl_history_search_internal (int count, int dir) { HIST_ENTRY *temp; int ret, oldpos, newcol; - char *t; oldpos = where_history (); /* where are we now? */ temp = (HIST_ENTRY *)NULL; @@ -650,6 +649,7 @@ rl_history_search_internal (int count, int dir) else { #if 0 + char *t; t = strstr (rl_line_buffer, history_search_string); /* XXX */ rl_point = t ? (int)(t - rl_line_buffer) + _rl_history_search_len : rl_end; #else diff --git a/lib/readline/shell.c b/lib/readline/shell.c index 7c0f9554..6f943de7 100644 --- a/lib/readline/shell.c +++ b/lib/readline/shell.c @@ -118,8 +118,10 @@ sh_single_quote (char *string) /* Set the environment variables LINES and COLUMNS to lines and cols, respectively. */ static char setenv_buf[INT_STRLEN_BOUND (int) + 1]; +#if defined (HAVE_PUTENV) && !defined (HAVE_SETENV) static char putenv_buf1[INT_STRLEN_BOUND (int) + 6 + 1]; /* sizeof("LINES=") == 6 */ static char putenv_buf2[INT_STRLEN_BOUND (int) + 8 + 1]; /* sizeof("COLUMNS=") == 8 */ +#endif void sh_set_lines_and_columns (int lines, int cols) diff --git a/lib/readline/terminal.c b/lib/readline/terminal.c index 2c70553d..e644e096 100644 --- a/lib/readline/terminal.c +++ b/lib/readline/terminal.c @@ -102,12 +102,20 @@ static char *term_string_buffer = (char *)NULL; static int tcap_initialized; -#if !defined (__linux__) && !defined (NCURSES_VERSION) -# if defined (__EMX__) || defined (NEED_EXTERN_PC) +/* Systems for which PC/BC/UP are defined in the curses library and need an + extern definition here. */ +#if !defined (__linux__) && !defined (__gnu_hurd__) && !defined (NCURSES_VERSION) +# define NEED_EXTERN_PC +#endif /* !__linux__ && !__gnu_hurd__ && !NCURSES_VERSION */ + +#if defined (__EMX__) +# define NEED_EXTERN_PC +#endif + +#if defined (NEED_EXTERN_PC) extern -# endif /* __EMX__ || NEED_EXTERN_PC */ +# endif /* NEED_EXTERN_PC */ char PC, *BC, *UP; -#endif /* !__linux__ && !NCURSES_VERSION */ /* Some strings to control terminal actions. These are output by tputs (). */ char *_rl_term_clreol; diff --git a/lib/readline/util.c b/lib/readline/util.c index 0a5df9b4..908a05f7 100644 --- a/lib/readline/util.c +++ b/lib/readline/util.c @@ -292,7 +292,7 @@ _rl_strpbrk (const char *string1, const char *string2) register const char *scan; #if defined (HANDLE_MULTIBYTE) mbstate_t ps; - register int i, v; + int v; memset (&ps, 0, sizeof (mbstate_t)); #endif diff --git a/support/install-sh b/support/install-sh new file mode 100644 index 00000000..8a76989b --- /dev/null +++ b/support/install-sh @@ -0,0 +1,541 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2024-12-03.03; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. + -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Report bugs to . +GNU Automake home page: . +General help using GNU software: ." + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -p) cpprog="$cpprog -p";; + + -s) stripcmd=$stripprog;; + + -S) backupsuffix="$2" + shift;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 (GNU Automake) $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibility with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp nil t) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/tests/braces.right b/tests/braces.right index 4a0c349d..b5c05b99 100644 --- a/tests/braces.right +++ b/tests/braces.right @@ -74,6 +74,10 @@ z x v t r p n l j h f d b {a..1} {a..2} {a..3} {a..4} {c..1} {c..2} {c..3} {c..4} {1..4} {2..4} {3..4} {6..7} {6..8} {6..9} +a ../a.cfg +a.. /a.cfg +a..b /a.cfg +a b../a.cfg {abcde.f} X{..a}Z 0{1..}2 diff --git a/tests/braces.tests b/tests/braces.tests index 848d1fa7..c3479159 100644 --- a/tests/braces.tests +++ b/tests/braces.tests @@ -141,6 +141,12 @@ echo {{a,c}..{1..4}} echo {{1,2,3}..4} echo {6..{7,8,9}} +# these are not valid sequence expressions but are valid brace expansions +echo {a,../a.cfg} +echo {a..,/a.cfg} +echo {a..b,/a.cfg} +echo {a,b../a.cfg} + # these are all invalid brace expansions echo {abcde.f}