ksh: Parse error during variable substitution

The closing quote does not appear to be registering during the parse of the following:

echo ${var:+'{}'}

Within a script, this will result in:

syntax error at line 1: `'' unmatched

This works correctly in the AST fork (Version AJM 93u+ 2012-08-01).

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 15

Commits related to this issue

Most upvoted comments

Unfortunately, the change does not completely fix the issue:

$ var=x; echo ${var:-'{}'}
x}
$ var=; echo ${var:+'{}'}
}

New patch, I think it’s fixed. Please test this.

Click to show patch
--- a/src/cmd/ksh93/data/lexstates.c
+++ b/src/cmd/ksh93/data/lexstates.c
@@ -387,6 +387,30 @@ static const char sh_lexstate9[256] =
 	0,	0,	0,	S_BRACE,S_PAT,	S_ENDCH,0,	0
 };
 
+/*
+ * ST_MOD1
+ * for skipping over a string S in ${v-S}, ${v+S}, ${v:-S}, ${v:+S}
+ */
+static const char sh_lexstate11[256] =
+{
+	S_EOF,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	S_NL,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	S_QUOTE,0,	S_DOL,	0,	0,	S_LIT,
+	0,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	S_ESC,	0,	0,	0,
+	S_GRAVE,0,	0,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	0,	0,	0,	0,
+	0,	0,	0,	0,	0,	S_RBRA,	0,	0
+};
+
 /*
  * This must be kept synchronous with all the above and the ST_* definitions in lexstates.h
  */
@@ -394,7 +418,7 @@ const char *sh_lexrstates[ST_NONE] =
 {
 	sh_lexstate0, sh_lexstate1, sh_lexstate2, sh_lexstate3,
 	sh_lexstate4, sh_lexstate5, sh_lexstate6, sh_lexstate7,
-	sh_lexstate8, sh_lexstate9, sh_lexstate5
+	sh_lexstate8, sh_lexstate9, sh_lexstate5, sh_lexstate11
 };
 
 
--- a/src/cmd/ksh93/include/lexstates.h
+++ b/src/cmd/ksh93/include/lexstates.h
@@ -79,7 +79,8 @@
 #define ST_DOLNAME	8
 #define ST_MACRO	9
 #define ST_QNEST	10
-#define ST_NONE		11
+#define ST_MOD1		11
+#define ST_NONE		12
 
 #include "FEATURE/locale"
 
--- a/src/cmd/ksh93/sh/lex.c
+++ b/src/cmd/ksh93/sh/lex.c
@@ -992,7 +992,7 @@ int sh_lex(Lex_t* lp)
 				mode = ST_NESTED;
 				continue;
 			case S_MOD1:
-				mode = ST_QUOTE;
+				mode = ST_MOD1;
 				continue;
 			case S_MOD2:
 #if SHOPT_KIA
--- a/src/cmd/ksh93/tests/quoting2.sh
+++ b/src/cmd/ksh93/tests/quoting2.sh
@@ -250,5 +250,18 @@ actual=$(printf %q $'1\x[11]1')
 [[ $actual == "$expect" ]] || err_exit 'shell-quoting: hex bytes not protected from subsequent hex-like chars' \
 				"(expected $expect; got $actual)"
 
+# ======
+# https://github.com/ksh93/ksh/issues/290
+var=dummy
+exp='{}'
+got=$(eval 'echo ${var:+'\''{}'\''}' 2>&1)
+[[ $got == "$exp" ]] || err_exit "Parse error during variable substitution (1)" \
+	"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
+unset var
+exp='}'
+got=$(eval 'echo ${var:-'\''}'\''}' 2>&1)
+[[ $got == "$exp" ]] || err_exit "Parse error during variable substitution (2)" \
+	"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
+
 # ======
 exit $((Errors<125?Errors:125))