[PATCH] loop.c: stop destructive unmetafy in selectlist()

LY <[email protected]>
Newsgroups gmane.comp.shells.zsh.devel
Message-ID <[email protected]>
selectlist() prints the option list and was calling unmetafy(*ap, NULL)
on each item in the print loop. The pointers returned by
hlinklist2array() alias the LinkList node buffers, so this mutation
permanently turned the metafied strings into raw UTF-8 in the very list
execselect() later reads back via getdata(n).

execselect() then passed those raw bytes to setsparam(), which expects
metafied input; the Meta byte 0x83 inside the now-unmetafied UTF-8 was
re-interpreted as an escape marker and the user's variable came out
mangled (e.g. select on "⚃" / U+269A produced \xe2\x2c\x83 instead of
\xe2\x9a\x83). The bug affected both the ZLE and non-ZLE paths since
both call selectlist().

Fix: drop the in-place unmetafy and print with zputs(), which already
handles metafied strings correctly.
---
 Src/loop.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Src/loop.c b/Src/loop.c
index db78f00c7..351edde89 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -377,13 +377,13 @@ selectlist(LinkList l, size_t start)
 	do {
 #ifdef MB_METASTRWIDTH
 	    size_t t2 = MB_METASTRWIDTH(*ap) + 2;
-	    (void) unmetafy(*ap, NULL);
 #else
 	    size_t t2 = strlen(*ap) + 2;
 #endif
-	    int t3;
+	    int t3 = ap - arr + 1;
 
-	    fprintf(stderr, "%d) %s", t3 = ap - arr + 1, *ap);
+	    fprintf(stderr, "%d) ", t3);
+	    zputs(*ap, stderr);
 	    while (t3)
 		t2++, t3 /= 10;
 	    for (; t2 < fw; t2++)
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.