builtin: Add CTLESC before all CCTLs in dollar single quote
If a backslash that comes from dollar-single quote escape sequence
is used as a pattern, it should be escaped automatically so that
it's interpreted as a literal backslash, rather than as a quoting
character.
Reported-by: Martijn Dekker <martijn@inlv.org>
Fixes: 776424a8f915 ("parser: Add dollar single quote")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/src/bltin/printf.c b/src/bltin/printf.c
index c2c3615..5355f5d 100644
--- a/src/bltin/printf.c
+++ b/src/bltin/printf.c
@@ -56,6 +56,7 @@
#include "bltin.h"
#include "parser.h"
+#include "syntax.h"
#include "system.h"
#define PF(f, func) { \
@@ -350,7 +351,7 @@
value = '\\';
- if (isodigit(ch)) {
+ if (unlikely(isodigit(ch))) {
ch = 3;
value = 0;
do {
@@ -362,8 +363,12 @@
str--;
check_value:
- if (mbchar && (signed char)value >= CTL_FIRST &&
- (signed char)value <= CTL_LAST)
+ if (SQSYNTAX[(signed char)value] != CCTL)
+ break;
+ /* fall through */
+
+ case '\\':
+ if (mbchar)
USTPUTC(CTLESC, out);
break;
@@ -395,12 +400,12 @@
value += d;
} while (--ch);
- if (value < 0x80)
- break;
-
if (och <= 2)
goto check_value;
+ if (value < 0x80)
+ goto check_value;
+
if (value < 0x110000) {
int mboff = (mbchar - 1) * 2;
unsigned uni = value;
@@ -442,9 +447,6 @@
ch = 4;
goto hex;
- case '\\':
- break;
-
case 'a': /* alert */
case 'b': /* backspace */
case 'f': /* form-feed */