Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Zsh - Multiple DoS Vulnerabilities



The following patch is one approach to fixing the last of these bugs.

There may be a cleaner approach relying on the WC_SUBLIST_END tags,
probably involving removing this whole block which is looking ahead to
the next wordcode rather than leaving it for the next iteration of the
big loop. But that would be a much bigger change with a greater chance
of breaking things.

The choice of "!" or "! " is a bit tricky and there may be some odd
cases remaining wherever ! is used without something to negate.

The code in exec.c that checks WC_SUBLIST_SKIP on the next code before
knowing that it is a sublist is harmless because it only assigns the
result to the next variable for later use. It still feels somewhat
impure to my taste but I've left it.

The patch also adds tests.

Oliver

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'
 #



Messages sorted by: Reverse Date, Date, Thread, Author