From: Chet Ramey Date: Fri, 28 Jun 2024 18:16:29 +0000 (-0400) Subject: size_t changes for multibyte characters; fix for running debug trap in asynchronous... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5e28a1813ce7d08628c8df584ea36515091c6d9b;p=thirdparty%2Fbash.git size_t changes for multibyte characters; fix for running debug trap in asynchronous pipeline; remove support for precomputed cache files for cross-compiling; more size_t and ssize_t changes to avoid overflow --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index bcbb64372..b716927aa 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -9677,3 +9677,47 @@ pathexp.c any non-digits sort after all-digit names and are sorted lexicographically. Inspired by a discussion with Robert Elz + + 6/21 + ---- +lib/readline/text.c + - rl_change_case: make mlen size_t to assign the return value from + wcrtomb; change the tests of < 0 to use MB_INVALIDCH. + Report from Siteshwar Vashisht + + 6/26 + ---- +trap.c + - run_debug_trap: give the terminal back to pipeline_pgrp only if + job_control is enabled; that's the only way the trap command would + have given it to a different process group + Fixes bug reported by Mark March + + 6/27 + ---- +configure.ac + - remove support for cached files for cross-compiling; it's too hard + to keep them up-to-date without access to the platforms + + 6/28 + ---- +lib/readline/util.c + - _rl_audit_tty: make sure to close fd before returning on error + +lib/sh/casemod.c + - sh_modcase: use size_t variable as return value for wcrtomb; check + for invalid wide char and copy all characters in the multibyte + character as-is if it is + +lib/sh/zwrite.c + - zwrite: use size_t and ssize_t variables + +builtins/evalfile.c + - _evalfile: use size_t variable for return value from strlen() + +lib/readline/funmap.c + - rl_funmap_names: don't bother calling qsort if result doesn't have + any entries + + All from a report by Siteshwar Vashisht + diff --git a/builtins/evalfile.c b/builtins/evalfile.c index 14a8488c8..9521934e5 100644 --- a/builtins/evalfile.c +++ b/builtins/evalfile.c @@ -78,7 +78,8 @@ _evalfile (const char *filename, int flags) { volatile int old_interactive; procenv_t old_return_catch; - int return_val, fd, result, pflags, i, nnull; + int return_val, fd, result, pflags, nnull; + size_t i; ssize_t nr; /* return value from read(2) */ char *string; struct stat finfo; @@ -101,19 +102,19 @@ _evalfile (const char *filename, int flags) do { fd = open (filename, O_RDONLY); - i = errno; - if (fd < 0 && i == EINTR) + result = errno; + if (fd < 0 && result == EINTR) QUIT; - errno = i; + errno = result; } while (fd < 0 && errno == EINTR && (flags & FEVAL_RETRY)); if (fd < 0 || (fstat (fd, &finfo) == -1)) { - i = errno; + result = errno; if (fd >= 0) close (fd); - errno = i; + errno = result; file_error_and_exit: if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT) diff --git a/builtins/printf.def b/builtins/printf.def index 4d663225a..6549e7186 100644 --- a/builtins/printf.def +++ b/builtins/printf.def @@ -1515,8 +1515,7 @@ asciicode (void) register intmax_t ch; #if defined (HANDLE_MULTIBYTE) wchar_t wc; - size_t slen; - int mblength; + size_t slen, mblength; #endif DECLARE_MBSTATE; @@ -1524,7 +1523,7 @@ asciicode (void) slen = strlen (garglist->word->word+1); wc = 0; mblength = mbrtowc (&wc, garglist->word->word+1, slen, &state); - if (mblength > 0) + if (MB_INVALIDCH (mblength) == 0) ch = wc; /* XXX */ else #endif diff --git a/configure b/configure index 6977651a0..285b73963 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac for Bash 5.3, version 5.065. +# From configure.ac for Bash 5.3, version 5.066. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.72 for bash 5.3-alpha. # @@ -5330,30 +5330,30 @@ SIGNAMES_H=lsignames.h CROSS_COMPILE= if test "x$cross_compiling" = "xyes"; then - case "${host}" in - *-cygwin*) - cross_cache=${srcdir}/cross-build/cygwin32.cache - ;; - *-msys*) - cross_cache=${srcdir}/cross-build/msys32.cache - ;; - *-mingw*) - cross_cache=${srcdir}/cross-build/cygwin32.cache - ;; - i[3456]86-*-beos*) - cross_cache=${srcdir}/cross-build/x86-beos.cache - ;; - *-qnx*) - cross_cache=${srcdir}/cross-build/qnx.cache - ;; - *) echo "configure: cross-compiling for $host is not supported" >&2 - ;; - esac - if test -n "${cross_cache}" && test -r "${cross_cache}"; then - echo "loading cross-build cache file ${cross_cache}" - . ${cross_cache} - fi - unset cross_cache +# case "${host}" in +# *-cygwin*) +# cross_cache=${srcdir}/cross-build/cygwin32.cache +# ;; +# *-msys*) +# cross_cache=${srcdir}/cross-build/msys32.cache +# ;; +# *-mingw*) +# cross_cache=${srcdir}/cross-build/cygwin32.cache +# ;; +# i[[3456]]86-*-beos*) +# cross_cache=${srcdir}/cross-build/x86-beos.cache +# ;; +# *-qnx*) +# cross_cache=${srcdir}/cross-build/qnx.cache +# ;; +# *) echo "configure: cross-compiling for $host is not supported" >&2 +# ;; +# esac +# if test -n "${cross_cache}" && test -r "${cross_cache}"; then +# echo "loading cross-build cache file ${cross_cache}" +# . ${cross_cache} +# fi +# unset cross_cache SIGNAMES_O='signames.o' CROSS_COMPILE='-DCROSS_COMPILING' diff --git a/configure.ac b/configure.ac index fe9306f46..b556b388d 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.065])dnl +AC_REVISION([for Bash 5.3, version 5.066])dnl define(bashvers, 5.3) define(relstatus, alpha) @@ -460,30 +460,30 @@ dnl Set SIGNAMES_H based on whether or not we're cross-compiling. CROSS_COMPILE= if test "x$cross_compiling" = "xyes"; then - case "${host}" in - *-cygwin*) - cross_cache=${srcdir}/cross-build/cygwin32.cache - ;; - *-msys*) - cross_cache=${srcdir}/cross-build/msys32.cache - ;; - *-mingw*) - cross_cache=${srcdir}/cross-build/cygwin32.cache - ;; - i[[3456]]86-*-beos*) - cross_cache=${srcdir}/cross-build/x86-beos.cache - ;; - *-qnx*) - cross_cache=${srcdir}/cross-build/qnx.cache - ;; - *) echo "configure: cross-compiling for $host is not supported" >&2 - ;; - esac - if test -n "${cross_cache}" && test -r "${cross_cache}"; then - echo "loading cross-build cache file ${cross_cache}" - . ${cross_cache} - fi - unset cross_cache +# case "${host}" in +# *-cygwin*) +# cross_cache=${srcdir}/cross-build/cygwin32.cache +# ;; +# *-msys*) +# cross_cache=${srcdir}/cross-build/msys32.cache +# ;; +# *-mingw*) +# cross_cache=${srcdir}/cross-build/cygwin32.cache +# ;; +# i[[3456]]86-*-beos*) +# cross_cache=${srcdir}/cross-build/x86-beos.cache +# ;; +# *-qnx*) +# cross_cache=${srcdir}/cross-build/qnx.cache +# ;; +# *) echo "configure: cross-compiling for $host is not supported" >&2 +# ;; +# esac +# if test -n "${cross_cache}" && test -r "${cross_cache}"; then +# echo "loading cross-build cache file ${cross_cache}" +# . ${cross_cache} +# fi +# unset cross_cache SIGNAMES_O='signames.o' CROSS_COMPILE='-DCROSS_COMPILING' AC_SUBST(CROSS_COMPILE) diff --git a/doc/bash.1 b/doc/bash.1 index 328a60944..c1df37543 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -9946,8 +9946,8 @@ any supplied field width and precision in terms of characters, not bytes. .PP Arguments to non-string format specifiers are treated as C constants, except that a leading plus or minus sign is allowed, and if the leading -character is a single or double quote, the value is the ASCII value of -the following character. +character is a single or double quote, the value is the numeric value of +the following character, using the current locale. .PP The \fIformat\fP is reused as necessary to consume all of the \fIarguments\fP. If the \fIformat\fP requires more \fIarguments\fP than are supplied, the diff --git a/doc/bashref.texi b/doc/bashref.texi index 26ea6d8c9..2e52db8f3 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -5091,8 +5091,8 @@ identically to the %b format specifier if it's supplied. Arguments to non-string format specifiers are treated as C language constants, except that a leading plus or minus sign is allowed, and if the leading -character is a single or double quote, the value is the ASCII value of -the following character. +character is a single or double quote, the value is the numeric value of +the following character, using the current locale. The @var{format} is reused as necessary to consume all of the @var{arguments}. If the @var{format} requires more @var{arguments} than are supplied, the diff --git a/lib/readline/complete.c b/lib/readline/complete.c index cae21cdbd..76bc252ca 100644 --- a/lib/readline/complete.c +++ b/lib/readline/complete.c @@ -1362,7 +1362,6 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text) size_t si1, si2; size_t len1, len2; #if defined (HANDLE_MULTIBYTE) - int v; size_t v1, v2; mbstate_t ps1, ps2; WCHAR_T wc1, wc2; diff --git a/lib/readline/display.c b/lib/readline/display.c index 7fdf23bdc..aff66ec35 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -1732,7 +1732,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l { char *ofd, *ols, *oe, *nfd, *nls, *ne; char *ofdf, *nfdf, *olsf, *nlsf; - int temp, lendiff, wsatend, od, nd, twidth, o_cpos; + int temp, lendiff, wsatend, od, nd, o_cpos; int current_invis_chars; int col_lendiff, col_temp; int bytes_to_insert; @@ -1863,7 +1863,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l _rl_output_some_chars below. */ if (newwidth > 0) { - int count, i, j; + int i, j; char *optr; puts_face (new, new_face, newbytes); diff --git a/lib/readline/examples/excallback.c b/lib/readline/examples/excallback.c index 04ecb1408..e8839d268 100644 --- a/lib/readline/examples/excallback.c +++ b/lib/readline/examples/excallback.c @@ -19,7 +19,7 @@ My example shows how, using the alternate interface, you can interactively change the prompt (which is very nice imo). Also, I point out that you must roll your own terminal setting when using the alternate interface because readline depreps (using your parlance) the -terminal while in the user callback. I try to demostrate what I mean +terminal while in the user callback. I try to demonstrate what I mean with an example. I've included the program below. To compile, I just put the program in the examples directory and made @@ -72,7 +72,7 @@ Copyright (C) 1999 Jeff Solomon * alternate interface. The first is the ability to interactively change the * prompt, which can't be done using the regular interface since rl_prompt is * read-only. - * + * * The second feature really highlights a subtle point when using the alternate * interface. That is, readline will not alter the terminal when inside your * callback handler. So let's so, your callback executes a user command that diff --git a/lib/readline/examples/histexamp.c b/lib/readline/examples/histexamp.c index 2e946acac..d592b7e10 100644 --- a/lib/readline/examples/histexamp.c +++ b/lib/readline/examples/histexamp.c @@ -110,7 +110,7 @@ main (int argc, char **argv) int which; if ((sscanf (line + 6, "%d", &which)) == 1) { - HIST_ENTRY *entry = remove_history (which); + HIST_ENTRY *entry = remove_history (which - history_base); if (!entry) fprintf (stderr, "No such entry %d\n", which); else diff --git a/lib/readline/examples/manexamp.c b/lib/readline/examples/manexamp.c index c8e11d5c8..ce33877f2 100644 --- a/lib/readline/examples/manexamp.c +++ b/lib/readline/examples/manexamp.c @@ -94,16 +94,8 @@ invert_case_line (int count, int key) start = rl_point; - if (count < 0) - { - direction = -1; - count = -count; - } - else - direction = 1; - /* Find the end of the range to modify. */ - end = start + (count * direction); + end = start + count; /* Force it to be within range. */ if (end > rl_end) @@ -111,6 +103,14 @@ invert_case_line (int count, int key) else if (end < 0) end = -1; + if (start == end) + return 0; + + /* For positive arguments, put point after the last changed character. For + negative arguments, put point before the last changed character. */ + rl_point = end; + + /* Swap start and end if we are moving backwards */ if (start > end) { int temp = start; @@ -118,14 +118,11 @@ invert_case_line (int count, int key) end = temp; } - if (start == end) - return 0; - /* Tell readline that we are modifying the line, so save the undo information. */ rl_modifying (start, end); - for (; start != end; start += direction) + for (; start != end; start++) { if (_rl_uppercase_p (rl_line_buffer[start])) rl_line_buffer[start] = _rl_to_lower (rl_line_buffer[start]); @@ -133,7 +130,5 @@ invert_case_line (int count, int key) rl_line_buffer[start] = _rl_to_upper (rl_line_buffer[start]); } - /* Move point to on top of the last character changed. */ - rl_point = end - direction; return 0; } diff --git a/lib/readline/funmap.c b/lib/readline/funmap.c index 548cfb572..28af3642c 100644 --- a/lib/readline/funmap.c +++ b/lib/readline/funmap.c @@ -265,6 +265,7 @@ rl_funmap_names (void) result[result_index + 1] = (char *)NULL; } - qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); + if (result) + qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); return (result); } diff --git a/lib/readline/nls.c b/lib/readline/nls.c index 8c027d6be..e04991dab 100644 --- a/lib/readline/nls.c +++ b/lib/readline/nls.c @@ -107,12 +107,13 @@ static int utf8locale (char *lspec) { char *cp; - size_t len; #if HAVE_LANGINFO_CODESET cp = nl_langinfo (CODESET); return (STREQ (cp, "UTF-8") || STREQ (cp, "utf8")); #else + size_t len; + cp = find_codeset (lspec, &len); if (cp == 0 || len < 4 || len > 5) diff --git a/lib/readline/text.c b/lib/readline/text.c index bb5655d2a..e8d4f5f65 100644 --- a/lib/readline/text.c +++ b/lib/readline/text.c @@ -1453,8 +1453,7 @@ rl_change_case (int count, int op) #if defined (HANDLE_MULTIBYTE) WCHAR_T wc, nwc; char mb[MB_LEN_MAX+1]; - int mlen; - size_t m; + size_t m, mlen; mbstate_t mps; #endif @@ -1532,12 +1531,13 @@ change_singlebyte: memset (&ts, 0, sizeof (mbstate_t)); mlen = WCRTOMB (mb, nwc, &ts); - if (mlen < 0) + + if (MB_INVALIDCH (mlen)) { nwc = wc; memset (&ts, 0, sizeof (mbstate_t)); mlen = WCRTOMB (mb, nwc, &ts); - if (mlen < 0) /* should not happen */ + if (MB_INVALIDCH (mlen)) /* should not happen */ strncpy (mb, rl_line_buffer + start, mlen = m); } if (mlen > 0) diff --git a/lib/readline/util.c b/lib/readline/util.c index 2a247034b..2bcc776ae 100644 --- a/lib/readline/util.c +++ b/lib/readline/util.c @@ -536,7 +536,10 @@ _rl_audit_tty (char *string) size = strlen (string) + 1; if (NLMSG_SPACE (size) > MAX_AUDIT_MESSAGE_LENGTH) - return; + { + close (fd); + return; + } memset (&req, 0, sizeof(req)); req.nlh.nlmsg_len = NLMSG_SPACE (size); diff --git a/lib/sh/casemod.c b/lib/sh/casemod.c index 6bef45863..acf5759c5 100644 --- a/lib/sh/casemod.c +++ b/lib/sh/casemod.c @@ -106,8 +106,7 @@ sh_modcase (const char *string, char *pat, int flags) #if defined (HANDLE_MULTIBYTE) wchar_t nwc; char mb[MB_LEN_MAX+1]; - int mlen; - size_t m; + size_t m, mlen; mbstate_t state; #endif @@ -249,8 +248,9 @@ singlebyte: else { mlen = wcrtomb (mb, nwc, &state); - if (mlen > 0) - mb[mlen] = '\0'; + if (MB_INVALIDCH (mlen)) + strncpy (mb, string + start, mlen = m); + mb[mlen] = '\0'; /* Don't assume the same width */ strncpy (ret + retind, mb, mlen); retind += mlen; diff --git a/lib/sh/zwrite.c b/lib/sh/zwrite.c index 54acc651e..0cea7f912 100644 --- a/lib/sh/zwrite.c +++ b/lib/sh/zwrite.c @@ -38,7 +38,9 @@ extern int errno; int zwrite (int fd, char *buf, size_t nb) { - int n, i, nt; + int nt; + size_t n; + ssize_t i; for (n = nb, nt = 0;;) { diff --git a/support/man2html.c b/support/man2html.c index 097f48ee5..954b91327 100644 --- a/support/man2html.c +++ b/support/man2html.c @@ -818,7 +818,7 @@ out_html(char *c) } else if (output_possible) { while (*c) { outbuffer[obp++] = *c; - if (*c == '\n' || obp > HUGE_STR_MAX) { + if (*c == '\n' || obp >= HUGE_STR_MAX) { outbuffer[obp] = '\0'; add_links(outbuffer); obp = 0; diff --git a/trap.c b/trap.c index 9acd19739..778e330d9 100644 --- a/trap.c +++ b/trap.c @@ -1286,7 +1286,9 @@ run_debug_trap (void) close_pgrp_pipe (); restore_pgrp_pipe (save_pipe); # endif - if (pipeline_pgrp > 0 && ((subshell_environment & (SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0)) + /* If the trap command gave the terminal to another process group, + restore it. XXX - check running_in_background? */ + if (job_control && pipeline_pgrp > 0 && ((subshell_environment & (SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0)) give_terminal_to (pipeline_pgrp, 1); notify_and_cleanup ();