bash: update to 5.3 patch level 9
authorWei-Ting Yang <redacted>
Thu, 8 Jan 2026 04:50:46 +0000 (12:50 +0800)
committerHannu Nyman <redacted>
Sun, 18 Jan 2026 05:19:05 +0000 (07:19 +0200)
- Fix posix-mode issue with "wait -n", where it can return process IDs
  outside the requested set
- Do not try to use shm_open, there is too much variance in behavior
  across systems
- Remove internal quoting that causes failures when expanding nested
  array subscripts in an arithmetic context
- Fix issue with source when read(2) returns fewer characters than
  fstat(2) says are available
- Fix crash when restoring default disposition for SIGINT in
  asynchronous subshell
- Fix issues with range expressions and non-ascii characters in glob
  patterns when globasciiranges is enabled
- Fix issue where nofork command substitutions can affect
  redirections in the calling shell
- Fix issue with calling mbrtowc too much when translating
  ansic-single-quoted strings
- Fix crash when interrupting reverse i-search with ^C

Signed-off-by: Wei-Ting Yang <redacted>
utils/bash/Makefile
utils/bash/patches/000-bash-5.3-patch-1.patch [new file with mode: 0644]
utils/bash/patches/001-bash-5.3-patch-2.patch [new file with mode: 0644]
utils/bash/patches/002-bash-5.3-patch-3.patch [new file with mode: 0644]
utils/bash/patches/003-bash-5.3-patch-4.patch [new file with mode: 0644]
utils/bash/patches/004-bash-5.3-patch-5.patch [new file with mode: 0644]
utils/bash/patches/005-bash-5.3-patch-6.patch [new file with mode: 0644]
utils/bash/patches/006-bash-5.3-patch-7.patch [new file with mode: 0644]
utils/bash/patches/007-bash-5.3-patch-8.patch [new file with mode: 0644]
utils/bash/patches/008-bash-5.3-patch-9.patch [new file with mode: 0644]

index 1d0312b2b48efd46b4f74dab33d6f4928a2846db..7bd91fd001ffabedd0e1ce5554ff2dbb94146d8b 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=bash
 PKG_VERSION:=5.3
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=@GNU/bash
diff --git a/utils/bash/patches/000-bash-5.3-patch-1.patch b/utils/bash/patches/000-bash-5.3-patch-1.patch
new file mode 100644 (file)
index 0000000..c643e6f
--- /dev/null
@@ -0,0 +1,27 @@
+From 21fee8ebcf03858a4c14b605095e89333ba159ba Mon Sep 17 00:00:00 2001
+From: Chet Ramey <chet.ramey@case.edu>
+Date: Wed, 23 Jul 2025 15:42:17 -0400
+Subject: Bash-5.3 patch 1: fix posix-mode issue with "wait -n", where it can
+ return process IDs outside the requested set
+
+--- a/jobs.c
++++ b/jobs.c
+@@ -3538,7 +3538,7 @@ return_procsub:
+   /* There aren't any dead jobs in the jobs table, but let's see if there's
+      one in bgpids. We can do this in posix mode because we'll remove any
+      one we find from the table, preserving existing semantics. */
+-  if (posixly_correct && (t = bgp_findone ()))
++  if (posixly_correct && (flags & JWAIT_WAITING) == 0 && (t = bgp_findone ()))
+     {
+       pid = t->pid;
+       r = t->status;
+--- a/patchlevel.h
++++ b/patchlevel.h
+@@ -25,6 +25,6 @@
+    regexp `^#define[  ]*PATCHLEVEL', since that's what support/mkversion.sh
+    looks for to find the patch level (for the sccs version string). */
+-#define PATCHLEVEL 0
++#define PATCHLEVEL 1
+ #endif /* _PATCHLEVEL_H_ */
diff --git a/utils/bash/patches/001-bash-5.3-patch-2.patch b/utils/bash/patches/001-bash-5.3-patch-2.patch
new file mode 100644 (file)
index 0000000..b75054b
--- /dev/null
@@ -0,0 +1,91 @@
+From 2ea3d6064911104d8e0437cb75b0e2559b0cd1b2 Mon Sep 17 00:00:00 2001
+From: Chet Ramey <chet.ramey@case.edu>
+Date: Wed, 23 Jul 2025 15:47:12 -0400
+Subject: Bash-5.3 patch 2: do not try to use shm_open, there is too much
+ variance in behavior across systems
+
+--- a/lib/sh/anonfile.c
++++ b/lib/sh/anonfile.c
+@@ -25,7 +25,7 @@
+ #endif
+ #include <bashtypes.h>
+-#if defined (HAVE_MEMFD_CREATE) || defined (HAVE_SHM_OPEN) || defined (HAVE_SHM_MKSTEMP)
++#if defined (HAVE_MEMFD_CREATE) || defined (HAVE_SHM_MKSTEMP)
+ #  include <sys/mman.h>
+ #endif
+ #include <filecntl.h>
+@@ -41,17 +41,7 @@ static int anonunlink (const char *);
+ #  define MFD_NOEXEC_SEAL 0
+ #endif
+-#if defined (HAVE_SHM_OPEN)
+-#ifndef O_NOFOLLOW
+-#  define O_NOFOLLOW 0
+-#endif
+-
+-static int
+-anonshmunlink (const char *fn)
+-{
+-  return (shm_unlink (fn));
+-}
+-
++#if defined (HAVE_SHM_MKSTEMP)
+ static int
+ anonshmopen (const char *name, int flags, char **fn)
+ {
+@@ -62,35 +52,14 @@ anonshmopen (const char *name, int flags
+   if (fn)
+     *fn = 0;
+-#if defined (HAVE_SHM_MKSTEMP)
+   fname = savestring ("/shm-XXXXXXXXXX");
+   fd = shm_mkstemp (fname);
+   if (fd < 0)
+-    free (fname);
+-#endif
+-
+-  if (fd < 0)
+-    {
+-      fname = sh_mktmpname (name, flags);
+-      fd = shm_open (fname, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600);
+-    }
+-
+-  if (fd < 0)
+     {
+       free (fname);
+       return fd;
+     }
+-  if (shm_unlink (fname) < 0)
+-    {
+-      int o;
+-      o = errno;
+-      free (fname);
+-      close (fd);
+-      errno = o;
+-      return -1;
+-    }
+-
+   if (fn)
+     *fn = fname;
+   else
+@@ -122,7 +91,7 @@ anonopen (const char *name, int flags, c
+   /* Heuristic */
+   flag = (name && *name == '/') ? MT_TEMPLATE : MT_USETMPDIR;
+-#if defined (HAVE_SHM_OPEN)
++#if defined (HAVE_SHM_MKSTEMP)
+   fd = anonshmopen (name, flag, fn);
+   if (fd >= 0)
+     return fd;                /* anonshmopen sets *FN appropriately */
+--- a/patchlevel.h
++++ b/patchlevel.h
+@@ -25,6 +25,6 @@
+    regexp `^#define[  ]*PATCHLEVEL', since that's what support/mkversion.sh
+    looks for to find the patch level (for the sccs version string). */
+-#define PATCHLEVEL 1
++#define PATCHLEVEL 2
+ #endif /* _PATCHLEVEL_H_ */
diff --git a/utils/bash/patches/002-bash-5.3-patch-3.patch b/utils/bash/patches/002-bash-5.3-patch-3.patch
new file mode 100644 (file)
index 0000000..5129f2d
--- /dev/null
@@ -0,0 +1,57 @@
+From 25c37d4804a9dbe0824ba805cc2b7cb94d243682 Mon Sep 17 00:00:00 2001
+From: Chet Ramey <chet.ramey@case.edu>
+Date: Wed, 23 Jul 2025 15:52:32 -0400
+Subject: Bash-5.3 patch 3: remove internal quoting that causes failures when
+ expanding nested array subscripts in an arithmetic context
+
+--- a/patchlevel.h
++++ b/patchlevel.h
+@@ -25,6 +25,6 @@
+    regexp `^#define[  ]*PATCHLEVEL', since that's what support/mkversion.sh
+    looks for to find the patch level (for the sccs version string). */
+-#define PATCHLEVEL 2
++#define PATCHLEVEL 3
+ #endif /* _PATCHLEVEL_H_ */
+--- a/subst.c
++++ b/subst.c
+@@ -3795,9 +3795,9 @@ pos_params (const char *string, int star
+ #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
+ #endif
+-/* We don't perform process substitution in arithmetic expressions, so don't
+-   bother checking for it. */
+-#define ARITH_EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
++/* We don't perform process substitution or tilde expansion in arithmetic
++   expressions, so don't bother checking for them. */
++#define ARITH_EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC)
+ /* If there are any characters in STRING that require full expansion,
+    then call FUNC to expand STRING; otherwise just perform quote
+@@ -12215,6 +12215,14 @@ string_quote_removal (const char *string
+             *r++ = '\\';
+             break;
+           }
++#if defined (ARRAY_VARS)
++        /* The only special characters that matter here are []~, since those
++           are backslash-quoted in expand_array_subscript but not dequoted
++           by the statement following this one. */
++        if ((quoted & Q_ARITH) && (c == LBRACK || c == RBRACK || c == '~'))
++          ;           /* placeholder here */
++        else
++#endif
+         if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
+           *r++ = '\\';
+         /* FALLTHROUGH */
+--- a/tests/quotearray.right
++++ b/tests/quotearray.right
+@@ -44,7 +44,7 @@ declare -A assoc=(["\` echo >&2 foo\`"]=
+ foo
+ 0
+ 0
+-./quotearray1.sub: line 68: 0\],b\[1: arithmetic syntax error: invalid arithmetic operator (error token is "\],b\[1")
++./quotearray1.sub: line 68: 0],b[1: arithmetic syntax error: invalid arithmetic operator (error token is "],b[1")
+ declare -a array
+ 0
+ 0
diff --git a/utils/bash/patches/003-bash-5.3-patch-4.patch b/utils/bash/patches/003-bash-5.3-patch-4.patch
new file mode 100644 (file)
index 0000000..4e62393
--- /dev/null
@@ -0,0 +1,29 @@
+From edff796a305b09fd991fd8e965d4c83bff91ee39 Mon Sep 17 00:00:00 2001
+From: Chet Ramey <chet.ramey@case.edu>
+Date: Wed, 26 Nov 2025 12:46:21 -0500
+Subject: Bash-5.3 patch 4: fix issue with source when read(2) returns fewer
+ characters than fstat(2) says are available
+
+--- a/builtins/evalfile.c
++++ b/builtins/evalfile.c
+@@ -160,8 +160,10 @@ file_error_and_exit:
+       nr = read (fd, string, file_size);
+       if (nr >= 0)
+       string[nr] = '\0';
++#if 0
+       if (nr != file_size)
+       nr = -1;                /* XXX - didn't get the whole file */
++#endif
+     }
+   else
+     nr = zmapfd (fd, &string, 0);
+--- a/patchlevel.h
++++ b/patchlevel.h
+@@ -25,6 +25,6 @@
+    regexp `^#define[  ]*PATCHLEVEL', since that's what support/mkversion.sh
+    looks for to find the patch level (for the sccs version string). */
+-#define PATCHLEVEL 3
++#define PATCHLEVEL 4
+ #endif /* _PATCHLEVEL_H_ */
diff --git a/utils/bash/patches/004-bash-5.3-patch-5.patch b/utils/bash/patches/004-bash-5.3-patch-5.patch
new file mode 100644 (file)
index 0000000..6efb0b7
--- /dev/null
@@ -0,0 +1,26 @@
+From f63f0134b19f303677a4371469158e4618967f63 Mon Sep 17 00:00:00 2001
+From: Chet Ramey <chet.ramey@case.edu>
+Date: Wed, 26 Nov 2025 12:47:49 -0500
+Subject: Bash-5.3 patch 5: fix crash when restoring default disposition for
+ SIGINT in asynchronous subshell
+
+--- a/patchlevel.h
++++ b/patchlevel.h
+@@ -25,6 +25,6 @@
+    regexp `^#define[  ]*PATCHLEVEL', since that's what support/mkversion.sh
+    looks for to find the patch level (for the sccs version string). */
+-#define PATCHLEVEL 4
++#define PATCHLEVEL 5
+ #endif /* _PATCHLEVEL_H_ */
+--- a/trap.c
++++ b/trap.c
+@@ -964,6 +964,7 @@ restore_default_signal (int sig)
+       original_signals[sig] = SIG_DFL;        /* XXX */
+       set_signal_handler (sig, SIG_DFL);
+       change_signal (sig, (char *)DEFAULT_SIG);
++      sigmodes[sig] &= ~SIG_TRAPPED;  /* no longer trapped */
+       return;
+     }
+     
diff --git a/utils/bash/patches/005-bash-5.3-patch-6.patch b/utils/bash/patches/005-bash-5.3-patch-6.patch
new file mode 100644 (file)
index 0000000..fe9e9fb
--- /dev/null
@@ -0,0 +1,27 @@
+From c31cd58e6c4d24cec178e9dc6d26a768b4ecbd1d Mon Sep 17 00:00:00 2001
+From: Chet Ramey <chet.ramey@case.edu>
+Date: Wed, 26 Nov 2025 12:49:17 -0500
+Subject: Bash-5.3 patch 6: fix issues with range expressions and non-ascii
+ characters in glob patterns when globasciiranges is enabled
+
+--- a/lib/glob/smatch.c
++++ b/lib/glob/smatch.c
+@@ -390,7 +390,7 @@ charcmp_wc (wint_t c1, wint_t c2, int fo
+   if (c1 == c2)
+     return 0;
+-  if (forcecoll == 0 && glob_asciirange && c1 <= UCHAR_MAX && c2 <= UCHAR_MAX)
++  if (forcecoll == 0 && glob_asciirange)
+     return ((int)(c1 - c2));
+   s1[0] = c1;
+--- a/patchlevel.h
++++ b/patchlevel.h
+@@ -25,6 +25,6 @@
+    regexp `^#define[  ]*PATCHLEVEL', since that's what support/mkversion.sh
+    looks for to find the patch level (for the sccs version string). */
+-#define PATCHLEVEL 5
++#define PATCHLEVEL 6
+ #endif /* _PATCHLEVEL_H_ */
diff --git a/utils/bash/patches/006-bash-5.3-patch-7.patch b/utils/bash/patches/006-bash-5.3-patch-7.patch
new file mode 100644 (file)
index 0000000..8f03859
--- /dev/null
@@ -0,0 +1,39 @@
+From a80c21e8b7ff113878ecece1db730fd40bc0ff55 Mon Sep 17 00:00:00 2001
+From: Chet Ramey <chet.ramey@case.edu>
+Date: Wed, 26 Nov 2025 12:50:54 -0500
+Subject: Bash-5.3 patch 7: fix issue where nofork command substitutions can
+ affect redirections in the calling shell
+
+--- a/patchlevel.h
++++ b/patchlevel.h
+@@ -25,6 +25,6 @@
+    regexp `^#define[  ]*PATCHLEVEL', since that's what support/mkversion.sh
+    looks for to find the patch level (for the sccs version string). */
+-#define PATCHLEVEL 6
++#define PATCHLEVEL 7
+ #endif /* _PATCHLEVEL_H_ */
+--- a/subst.c
++++ b/subst.c
+@@ -206,6 +206,8 @@ extern int wordexp_only;
+ extern int singlequote_translations;
+ extern int extended_quote;
++extern REDIRECT *exec_redirection_undo_list, *redirection_undo_list;
++
+ #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
+ extern wchar_t *wcsdup (const wchar_t *);
+ #endif
+@@ -7000,6 +7002,11 @@ function_substitute (char *string, int q
+       add_unwind_protect (uw_restore_pipestatus_array, psa);
+     }
+ #endif
++
++  unwind_protect_pointer (redirection_undo_list);
++  redirection_undo_list = NULL;
++  unwind_protect_pointer (exec_redirection_undo_list);
++  exec_redirection_undo_list = NULL;
+   
+   subst_assign_varlist = 0;
diff --git a/utils/bash/patches/007-bash-5.3-patch-8.patch b/utils/bash/patches/007-bash-5.3-patch-8.patch
new file mode 100644 (file)
index 0000000..ea49e91
--- /dev/null
@@ -0,0 +1,167 @@
+From 11ff9325c1497c5ef1de7cf6fde84e1094eae178 Mon Sep 17 00:00:00 2001
+From: Chet Ramey <chet.ramey@case.edu>
+Date: Wed, 26 Nov 2025 12:52:29 -0500
+Subject: Bash-5.3 patch 8: fix issue with calling mbrtowc too much when
+ translating ansic-single-quoted strings
+
+--- a/lib/sh/strtrans.c
++++ b/lib/sh/strtrans.c
+@@ -55,7 +55,7 @@ ansicstr (const char *string, size_t len
+   const char *s;
+   unsigned long v;
+   size_t clen;
+-  int mb_cur_max;
++  size_t mb_cur_max;
+ #if defined (HANDLE_MULTIBYTE)
+   wchar_t wc;
+ #endif
+@@ -63,7 +63,7 @@ ansicstr (const char *string, size_t len
+   if (string == 0 || *string == '\0')
+     return ((char *)0);
+-  mb_cur_max = MB_CUR_MAX;
++  mb_cur_max = locale_mb_cur_max;
+ #if defined (HANDLE_MULTIBYTE)
+   temp = 4*len + 4;
+   if (temp < 12)
+@@ -79,10 +79,14 @@ ansicstr (const char *string, size_t len
+       {
+         clen = 1;
+ #if defined (HANDLE_MULTIBYTE)
+-        if ((locale_utf8locale && (c & 0x80)) ||
+-            (locale_utf8locale == 0 && mb_cur_max > 0 && is_basic (c) == 0))
++        /* We read an entire multibyte character at a time if we are in a
++           locale where a backslash can possibly appear as part of a
++           multibyte character. UTF-8 encodings prohibit this. */
++        if (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0)
+           {
+             clen = mbrtowc (&wc, s - 1, mb_cur_max, 0);
++            if (MB_NULLWCH (clen))
++              break;                  /* it apparently can happen */
+             if (MB_INVALIDCH (clen))
+               clen = 1;
+           }
+@@ -227,30 +231,24 @@ ansic_quote (const char *str, int flags,
+ {
+   char *r, *ret;
+   const char  *s;
+-  size_t l, rsize;
+   unsigned char c;
++#if defined (HANDLE_MULTIBYTE)
+   size_t clen;
+   int b;
+-#if defined (HANDLE_MULTIBYTE)
+   wchar_t wc;
++  DECLARE_MBSTATE;
+ #endif
+   if (str == 0 || *str == 0)
+     return ((char *)0);
+-  l = strlen (str);
+-  rsize = 4 * l + 4;
+-  r = ret = (char *)xmalloc (rsize);
++  r = ret = (char *)xmalloc (4 * strlen (str) + 4);
+   *r++ = '$';
+   *r++ = '\'';
+   for (s = str; c = *s; s++)
+     {
+-      b = 1;          /* 1 == add backslash; 0 == no backslash */
+-      l = 1;
+-      clen = 1;
+-
+       switch (c)
+       {
+       case ESC: c = 'E'; break;
+@@ -266,39 +264,42 @@ ansic_quote (const char *str, int flags,
+         break;
+       default:
+ #if defined (HANDLE_MULTIBYTE)
+-        b = is_basic (c);
+-        /* XXX - clen comparison to 0 is dicey */
+-        if ((b == 0 && ((clen = mbrtowc (&wc, s, MB_CUR_MAX, 0)) < 0 || MB_INVALIDCH (clen) || iswprint (wc) == 0)) ||
+-            (b == 1 && ISPRINT (c) == 0))
+-#else
+-        if (ISPRINT (c) == 0)
+-#endif
++        if ((locale_utf8locale && (c & 0x80)) ||
++            (locale_utf8locale == 0 && locale_mb_cur_max > 1 && is_basic (c) == 0))
+           {
+-            *r++ = '\\';
+-            *r++ = TOCHAR ((c >> 6) & 07);
+-            *r++ = TOCHAR ((c >> 3) & 07);
+-            *r++ = TOCHAR (c & 07);
+-            continue;
++            clen = mbrtowc (&wc, s, locale_mb_cur_max, &state);
++            if (MB_NULLWCH (clen))
++              goto quote_end;
++            if (MB_INVALIDCH (clen))
++              INITIALIZE_MBSTATE;
++            else if (iswprint (wc))
++              {
++                for (b = 0; b < (int)clen; b++)
++                  *r++ = (unsigned char)s[b];
++                s += clen - 1;        /* -1 because of the increment above */
++                continue;
++              }
+           }
+-        l = 0;
+-        break;
++        else
++#endif
++          if (ISPRINT (c))
++            {
++              *r++ = c;
++              continue;
++            }
++
++        *r++ = '\\';
++        *r++ = TOCHAR ((c >> 6) & 07);
++        *r++ = TOCHAR ((c >> 3) & 07);
++        *r++ = TOCHAR (c & 07);
++        continue;
+       }
+-      if (b == 0 && clen == 0)
+-      break;
+-      if (l)
+-      *r++ = '\\';
+-
+-      if (clen == 1)
+-      *r++ = c;
+-      else
+-      {
+-        for (b = 0; b < (int)clen; b++)
+-          *r++ = (unsigned char)s[b];
+-        s += clen - 1;        /* -1 because of the increment above */
+-      }
++      *r++ = '\\';
++      *r++ = c;
+     }
++quote_end:
+   *r++ = '\'';
+   *r = '\0';
+   if (rlen)
+@@ -348,7 +349,8 @@ ansic_shouldquote (const char *string)
+   for (s = string; c = *s; s++)
+     {
+ #if defined (HANDLE_MULTIBYTE)
+-      if (is_basic (c) == 0)
++      if ((locale_utf8locale && (c & 0x80)) ||
++        (locale_utf8locale == 0 && locale_mb_cur_max > 1 && is_basic (c) == 0))
+       return (ansic_wshouldquote (s));
+ #endif
+       if (ISPRINT (c) == 0)
+--- a/patchlevel.h
++++ b/patchlevel.h
+@@ -25,6 +25,6 @@
+    regexp `^#define[  ]*PATCHLEVEL', since that's what support/mkversion.sh
+    looks for to find the patch level (for the sccs version string). */
+-#define PATCHLEVEL 7
++#define PATCHLEVEL 8
+ #endif /* _PATCHLEVEL_H_ */
diff --git a/utils/bash/patches/008-bash-5.3-patch-9.patch b/utils/bash/patches/008-bash-5.3-patch-9.patch
new file mode 100644 (file)
index 0000000..99fbe74
--- /dev/null
@@ -0,0 +1,53 @@
+From 637f5c8696a6adc9b4519f1cd74aa78492266b7f Mon Sep 17 00:00:00 2001
+From: Chet Ramey <chet.ramey@case.edu>
+Date: Wed, 10 Dec 2025 11:30:51 -0500
+Subject: Bash-5.3 patch 9: fix crash when interrupting reverse i-search with
+ ^C
+
+--- a/lib/readline/input.c
++++ b/lib/readline/input.c
+@@ -971,11 +971,11 @@ postproc_signal:
+        call the application's signal event hook. */
+       if (rl_signal_event_hook)
+       (*rl_signal_event_hook) ();
+-#if defined (READLINE_CALLBACKS)
+-      else if (osig == SIGINT && (ostate & RL_STATE_CALLBACK) && (ostate & (RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_NUMERICARG)))
++      /* If the application's SIGINT handler returns, make sure we abort out of
++       searches and numeric arguments because we've freed necessary state. */
++      if (osig == SIGINT && (ostate & (RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_NUMERICARG)))
+         /* just these cases for now */
+         _rl_abort_internal ();
+-#endif
+     }
+ }
+--- a/lib/readline/isearch.c
++++ b/lib/readline/isearch.c
+@@ -889,12 +889,14 @@ opcode_dispatch:
+ int
+ _rl_isearch_cleanup (_rl_search_cxt *cxt, int r)
+ {
++  RL_UNSETSTATE(RL_STATE_ISEARCH);
++  if (cxt == 0)
++    return (r != 0);
++
++  _rl_iscxt = 0;
+   if (r >= 0)
+     _rl_isearch_fini (cxt);
+   _rl_scxt_dispose (cxt, 0);
+-  _rl_iscxt = 0;
+-
+-  RL_UNSETSTATE(RL_STATE_ISEARCH);
+   return (r != 0);
+ }
+--- a/patchlevel.h
++++ b/patchlevel.h
+@@ -25,6 +25,6 @@
+    regexp `^#define[  ]*PATCHLEVEL', since that's what support/mkversion.sh
+    looks for to find the patch level (for the sccs version string). */
+-#define PATCHLEVEL 8
++#define PATCHLEVEL 9
+ #endif /* _PATCHLEVEL_H_ */
git clone https://git.99rst.org/PROJECT