← Commit list

8de5b9f88

Denys Vlasenko
Denys Vlasenko
2018-02-13
SUCCESS Duration: 145s

Subject

ash : fix double-quoted "\z" handling

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

shell/ash.c+17 -6
@@ -6146,12 +6146,12 @@ rmescapes(char *str, int flag, int *slash_position)
if (*p == '*'
|| *p == '?'
|| *p == '['
- || *p == '\\' /* case '\' in \\ ) echo ok;; *) echo WRONG;; esac */
- || *p == ']' /* case ']' in [a\]] ) echo ok;; *) echo WRONG;; esac */
- || *p == '-' /* case '-' in [a\-c]) echo ok;; *) echo WRONG;; esac */
- || *p == '!' /* case '!' in [\!] ) echo ok;; *) echo WRONG;; esac */
+ || *p == '\\' /* case '\' in \\ ) echo ok;; *) echo WRONG;; esac */
+ || *p == ']' /* case ']' in [a\]] ) echo ok;; *) echo WRONG;; esac */
+ || *p == '-' /* case '-' in [a\-c]) echo ok;; *) echo WRONG;; esac */
+ || *p == '!' /* case '!' in [\!] ) echo ok;; *) echo WRONG;; esac */
/* Some libc support [^negate], that's why "^" also needs love */
- || *p == '^' /* case '^' in [\^] ) echo ok;; *) echo WRONG;; esac */
+ || *p == '^' /* case '^' in [\^] ) echo ok;; *) echo WRONG;; esac */
) {
*q++ = '\\';
}
@@ -11992,13 +11992,24 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
USTPUTC(CTLESC, out);
USTPUTC('\\', out);
}
- /* Backslash is retained if we are in "str" and next char isn't special */
+ /* Backslash is retained if we are in "str"
+ * and next char isn't dquote-special.
+ */
if (dblquote
&& c != '\\'
&& c != '`'
&& c != '$'
&& (c != '"' || eofmark != NULL)
) {
+//dash survives not doing USTPUTC(CTLESC), but merely by chance:
+//Example: "\z" gets encoded as "\<CTLESC>z".
+//rmescapes() then emits "\", "\z", protecting z from globbing.
+//But it's wrong, should protect _both_ from globbing:
+//everything in double quotes is not globbed.
+//Unlike dash, we have a fix in rmescapes() which emits bare "z"
+//for "<CTLESC>z" since "z" is not glob-special (else unicode may break),
+//and glob would see "\z" and eat "\". Thus:
+ USTPUTC(CTLESC, out); /* protect '\' from glob */
USTPUTC('\\', out);
}
USTPUTC(CTLESC, out);
shell/ash_test/ash-quoting/bkslash_case1.right+10 -0
@@ -0,0 +1,10 @@
+ok1
+ok2
+ok3
+ok4
+ok5
+Ok:0
+ok6
+ok7
+ok8
+Ok:0
shell/ash_test/ash-quoting/bkslash_case1.tests+38 -0
@@ -0,0 +1,38 @@
+# Case argument is globbed, match patterns are not.
+# This caught some bugs in the past.
+
+case z in
+\z ) echo ok1 ;;
+* ) echo BUG ;;
+esac
+case \z in
+z ) echo ok2 ;;
+* ) echo BUG ;;
+esac
+case \z in
+\z ) echo ok3 ;;
+* ) echo BUG ;;
+esac
+case z in
+\z ) echo ok4 ;;
+* ) echo BUG ;;
+esac
+case \\z in
+\\z ) echo ok5 ;;
+* ) echo BUG ;;
+esac
+echo Ok:$?
+
+case "\z" in
+"\z" ) echo ok6 ;;
+* ) echo BUG ;;
+esac
+case "\\z" in
+"\\z" ) echo ok7 ;;
+* ) echo BUG ;;
+esac
+case "\\\z" in
+"\\\z") echo ok8 ;;
+* ) echo BUG ;;
+esac
+echo Ok:$?
shell/hush_test/hush-quoting/bkslash_case1.right+10 -0
@@ -0,0 +1,10 @@
+ok1
+ok2
+ok3
+ok4
+ok5
+Ok:0
+ok6
+ok7
+ok8
+Ok:0
shell/hush_test/hush-quoting/bkslash_case1.tests+38 -0
@@ -0,0 +1,38 @@
+# Case argument is globbed, match patterns are not.
+# This caught some bugs in the past.
+
+case z in
+\z ) echo ok1 ;;
+* ) echo BUG ;;
+esac
+case \z in
+z ) echo ok2 ;;
+* ) echo BUG ;;
+esac
+case \z in
+\z ) echo ok3 ;;
+* ) echo BUG ;;
+esac
+case z in
+\z ) echo ok4 ;;
+* ) echo BUG ;;
+esac
+case \\z in
+\\z ) echo ok5 ;;
+* ) echo BUG ;;
+esac
+echo Ok:$?
+
+case "\z" in
+"\z" ) echo ok6 ;;
+* ) echo BUG ;;
+esac
+case "\\z" in
+"\\z" ) echo ok7 ;;
+* ) echo BUG ;;
+esac
+case "\\\z" in
+"\\\z") echo ok8 ;;
+* ) echo BUG ;;
+esac
+echo Ok:$?