diff --git a/ChangeLog b/ChangeLog
index a5b9e08f5..e24d47196 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-08-23 Peter Stephenson
+
+ * 23795: Src/lex.c: make ${(Q)...} handle $'...' correctly,
+ up to the problem of long flies in short ointments.
+
2007-08-23 Peter Stephenson
* unposted: Functions/Calendar/calendar_show: used subscript
diff --git a/Config/version.mk b/Config/version.mk
index 3fe2df89a..31848812e 100644
--- a/Config/version.mk
+++ b/Config/version.mk
@@ -27,5 +27,5 @@
# This must also serve as a shell script, so do not add spaces around the
# `=' signs.
-VERSION=4.3.4-dev-0
-VERSION_DATE='April 19, 2006'
+VERSION=4.3.4-dev-1
+VERSION_DATE='August 1, 2007'
diff --git a/Src/lex.c b/Src/lex.c
index 8bf90847a..a334dc722 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -1556,6 +1556,7 @@ mod_export int
parse_subst_string(char *s)
{
int c, l = strlen(s), err, olen, lexstop_ret;
+ char *ptr;
if (!*s || !strcmp(s, nulstring))
return 0;
@@ -1593,6 +1594,43 @@ parse_subst_string(char *s)
return 1;
}
#endif
+ /* Check for $'...' quoting. This needs special handling. */
+ for (ptr = s; *ptr; )
+ {
+ if (*ptr == String && ptr[1] == Snull)
+ {
+ char *t;
+ int len, tlen, diff;
+ t = getkeystring(ptr + 2, &len, GETKEYS_DOLLARS_QUOTE, NULL);
+ len += 2;
+ tlen = strlen(t);
+ diff = len - tlen;
+ /*
+ * Yuk.
+ * parse_subst_string() currently handles strings in-place.
+ * That's not so easy to fix without knowing whether
+ * additional memory should come off the heap or
+ * otherwise. So we cheat by copying the unquoted string
+ * into place, unless it's too long. That's not the
+ * normal case, but I'm worried there are are pathological
+ * cases with converting metafied multibyte strings.
+ * If someone can prove there aren't I will be very happy.
+ */
+ if (diff < 0) {
+ DPUTS(1, "$'...' subst too long: fix get_parse_string()");
+ return 1;
+ }
+ memcpy(ptr, t, tlen);
+ ptr += tlen;
+ if (diff > 0) {
+ char *dptr = ptr;
+ char *sptr = ptr + diff;
+ while ((*dptr++ = *sptr++))
+ ;
+ }
+ } else
+ ptr++;
+ }
return 0;
}
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index 7f229e9a6..1910e60be 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -320,6 +320,11 @@
0:${(Q)...}
>and now even the pubs are shut.
+ foo="X$'\x41'$'\x42'Y"
+ print -r ${(Q)foo}
+0:${(Q)...} with handling of $'...'
+>XABY
+
psvar=(dog)
setopt promptsubst
foo='It shouldn'\''t $(happen) to a %1v.'