On Mon, Nov 4, 2024 at 6:17 PM William DeShazer <earl.deshazer@xxxxxxxxx> wrote:
You mentioned, or the issue that you referenced, mentioned that it was a zle interaction.
Just a similarity, pointing to a potential issue with wcwidth(), not a
suggestion that zle is actually involved in this case.
But that turns out to be a red herring ... it is getsparam_u() after all.
getsparam_u() calls getsparam() which calls fetchvalue(), which
returns a Value with a pointer to the Param struct in the global
parameter hash, then calls getstrvalue() on that, which returns a
pointer to the string in the Param, which unmetafy() then modifies in
place. Subsequent unmetafy() are no-ops during following calls to
sourcehome() but actual parameter expansions expect the value in the
global to be stored metafied.
Possible solutions are to use unmeta(), which is more efficient but
returns a pointer to a single-use buffer (that is, a subsequent call
to unmeta() will clobber it):
diff --git a/Src/params.c b/Src/params.c
index acd577527..25a831ed7 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -3065,7 +3065,7 @@ mod_export char *
getsparam_u(char *s)
{
if ((s = getsparam(s)))
- return unmetafy(s, NULL);
+ return unmeta(s);
return s;
}
Or to explicitly allocate space on the heap:
diff --git a/Src/params.c b/Src/params.c
index acd577527..99c979b85 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -3065,7 +3065,7 @@ mod_export char *
getsparam_u(char *s)
{
if ((s = getsparam(s)))
- return unmetafy(s, NULL);
+ return unmetafy(dupstring(s), NULL);
return s;
}
Looking at the uses of getsparam_u() the returned pointer is always
immediately used and discarded so I think unmeta() is safe. Thoughts,
-workers?