Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
[PATCH] loop.c: stop destructive unmetafy in selectlist()
- X-seq: zsh-workers 54583
- From: LY <ly-niko@xxxxxx>
- To: zsh-workers@xxxxxxx
- Cc: LY <ly-niko@xxxxxx>
- Subject: [PATCH] loop.c: stop destructive unmetafy in selectlist()
- Date: Wed, 20 May 2026 18:26:12 +0800
- Archived-at: <https://zsh.org/workers/54583>
- List-id: <zsh-workers.zsh.org>
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
Messages sorted by:
Reverse Date,
Date,
Thread,
Author