From a531a1ec2dce97c1507a45abd4795b1aea1edc9e Mon Sep 17 00:00:00 2001
From: Oliver Kiddle <okiddle@yahoo.co.uk>
Date: Thu, 23 May 2019 01:05:01 +0200
Subject: [PATCH 225/262] 44345: fix wordcode traversal where ! without a
 following command could result in a crash

---
 ChangeLog            |  5 +++++
 Src/text.c           |  9 +++++++--
 Test/A01grammar.ztst | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/Src/text.c b/Src/text.c
index 3658b1bc6..a4191bf1a 100644
--- a/Src/text.c
+++ b/Src/text.c
@@ -470,8 +470,13 @@ gettext2(Estate state)
 			    " || " : " && ");
 		    s->code = *state->pc++;
 		    s->pop = (WC_SUBLIST_TYPE(s->code) == WC_SUBLIST_END);
-		    if (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_NOT)
-			taddstr("! ");
+		    if (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_NOT) {
+			if (WC_SUBLIST_SKIP(s->code) == 0)
+			    stack = 1;
+			taddstr((stack || (!(WC_SUBLIST_FLAGS(s->code) &
+			        WC_SUBLIST_SIMPLE) && wc_code(*state->pc) !=
+			        WC_PIPE)) ? "!" : "! ");
+		    }
 		    if (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_COPROC)
 			taddstr("coproc ");
 		}
diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst
index 1ed3cb6b7..c8600d4cb 100644
--- a/Test/A01grammar.ztst
+++ b/Test/A01grammar.ztst
@@ -76,6 +76,39 @@
 0:Basic current shell list with error
 >false
 
+  fn() { : && ! ; : }
+  functions -x3 fn
+  fn
+0:End of sublist containing ! with no command
+>fn () {
+>   : && !
+>   :
+>}
+
+  if [[ m -eq y ]]; then
+    : && !
+    :
+  fi
+0:! followed by no further commands
+
+  fn() { ! {!} && ! (!) || ! {!} }
+  functions -x2 fn
+  fn
+0:exclamation marks without following commands
+>fn () {
+>  ! {
+>    !
+>  } && ! (
+>    !
+>  ) || ! {
+>    !
+>  }
+>}
+
+  ! | true
+1:! followed by no command but by a pipe
+?(eval):1: parse error near `|'
+
 #
 # Tests for `Precommand Modifiers'
 #
-- 
2.19.1

