Re: dash bug: double-quoted "\" breaks glob protection for next char

2018-02-14 Thread Harald van Dijk

On 2/14/18 10:44 PM, Harald van Dijk wrote:

On 2/14/18 9:03 PM, Harald van Dijk wrote:

On 13/02/2018 14:53, Denys Vlasenko wrote:

$ >'\'
$ >'\'
$ dash -c 'echo "\*"'
\ \


[...]

Currently:

$ dash -c 'foo=a; echo "<${foo#[a\]]}>"'
<>

This is what I expect, and also what bash, ksh and posh do.

With your patch:

$ dash -c 'foo=a; echo "<${foo#[a\]]}>"'



Does the attached look right as an alternative? It treats a quoted 
backslash the same way as if it were preceded by CTLESC in _rmescapes. 
It passes your test case and mine, but I'll do more extensive testing.


It causes preglob's string to potentially grow larger than the original. 
When called with RMESCAPE_ALLOC, that can be handled by increasing the 
buffer size, but preglob also gets called without RMESCAPE_ALLOC to 
modify a string in-place. That's never going to work with this approach. 
Back to the drawing board...


Cheers,
Harald van Dijk
--
To unsubscribe from this list: send the line "unsubscribe dash" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: dash bug: double-quoted "\" breaks glob protection for next char

2018-02-14 Thread Harald van Dijk

On 2/14/18 9:03 PM, Harald van Dijk wrote:

On 13/02/2018 14:53, Denys Vlasenko wrote:

$ >'\'
$ >'\'
$ dash -c 'echo "\*"'
\ \


[...]

Currently:

$ dash -c 'foo=a; echo "<${foo#[a\]]}>"'
<>

This is what I expect, and also what bash, ksh and posh do.

With your patch:

$ dash -c 'foo=a; echo "<${foo#[a\]]}>"'



Does the attached look right as an alternative? It treats a quoted 
backslash the same way as if it were preceded by CTLESC in _rmescapes. 
It passes your test case and mine, but I'll do more extensive testing.


Cheers,
Harald van Dijk
diff --git a/src/expand.c b/src/expand.c
index 2a50830..af88a69 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -1686,12 +1686,17 @@ _rmescapes(char *str, int flag)
 		}
 		if (*p == (char)CTLESC) {
 			p++;
-			if (notescaped)
-*q++ = '\\';
-		} else if (*p == '\\' && !inquotes) {
-			/* naked back slash */
-			notescaped = 0;
-			goto copy;
+			goto escape;
+		} else if (*p == '\\') {
+			if (inquotes) {
+escape:
+if (notescaped)
+	*q++ = '\\';
+			} else {
+/* naked back slash */
+notescaped = 0;
+goto copy;
+			}
 		}
 		notescaped = globbing;
 copy:


Re: dash bug: double-quoted "\" breaks glob protection for next char

2018-02-14 Thread Harald van Dijk

On 13/02/2018 14:53, Denys Vlasenko wrote:

$ >'\'
$ >'\'
$ dash -c 'echo "\*"'
\ \


Nice catch.


The cause: uses "\\*" pattern instead of "\\\*".
The fix:

 /* backslash */
 case CBACK:
 c = pgetc2();
 if (c == PEOF) {
 USTPUTC(CTLESC, out);
 USTPUTC('\\', out);
 pungetc();
 } else if (c == '\n') {
 nlprompt();
 } else {
 if (
 dblquote &&
 c != '\\' && c != '`' &&
 c != '$' && (
 c != '"' ||
 eofmark != NULL
 )
 ) {
USTPUTC(CTLESC, out); // add this line
 USTPUTC('\\', out);
 }
 USTPUTC(CTLESC, out);
 USTPUTC(c, out);
 quotef++;
 }


I don't think this is right. The bug was introduced in




Prior to that, the line USTPUTC(CTLESC, out); was there. The commit 
message is saying that the logic for detecting whether \ should be taken 
literally doesn't belong in the parser, that the parser will get it 
wrong. The example in the commit message doesn't break with your patch, 
but short modifications to that example do make it fail:


Currently:

$ dash -c 'foo=a; echo "<${foo#[a\]]}>"'
<>

This is what I expect, and also what bash, ksh and posh do.

With your patch:

$ dash -c 'foo=a; echo "<${foo#[a\]]}>"'


Cheers,
Harald van Dijk
--
To unsubscribe from this list: send the line "unsubscribe dash" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html