Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [BUG] Strange auto-load behaviour when function name contains hyphen



On 14 Dec 2017, at 11:21, dana <dana@xxxxxxx> wrote:
>The patch seems to work for me if i change the condition to this:

Understanding a bit more about the token thing, i went and tested some of the
others defined in zsh.h. The same problem occurs if you have a function name
containing almost any of them. Also, if your function name is quoted or escaped,
the tokens for those meta-characters are present and have to be dealt with for
the comparison too.

I'm not sure why someone would use an asterisk or whatever in a function name,
but i can't find anything in the documentation that says you shouldn't (and i'm
not aware of any issues doing so aside from this).

Should it perform a more comprehensive check? Something like the following?
Possibly it could be optimised to avoid going through the whole dance when it
doesn't need to (considering it's an edge case)...

dana


diff --git a/Src/exec.c b/Src/exec.c
index fc6d02dc3..4c096fd12 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -5932,6 +5932,7 @@ stripkshdef(Eprog prog, char *name)
 {
     Wordcode pc;
     wordcode code;
+    char *pname, *litpname;
 
     if (!prog)
 	return NULL;
@@ -5942,10 +5943,25 @@ stripkshdef(Eprog prog, char *name)
 	return prog;
     pc++;
     code = *pc++;
-    if (wc_code(code) != WC_FUNCDEF ||
-	*pc != 1 || strcmp(name, ecrawstr(prog, pc + 1, NULL)))
+    if (wc_code(code) != WC_FUNCDEF || *pc != 1)
 	return prog;
 
+    /*
+     * Detokenise and literalise the name in the word code (it may be quoted)
+     * and make sure it matches the expected name
+     */
+    pname = ecrawstr(prog, pc + 1, NULL);
+    litpname = ztrdup(pname);
+    parse_subst_string(litpname);
+    remnulargs(litpname);
+    untokenize(litpname);
+
+    if (strcmp(name, litpname)) {
+	free(litpname);
+	return prog;
+    }
+    free(litpname);
+
     {
 	Eprog ret;
 	Wordcode end = pc + WC_FUNCDEF_SKIP(code);
diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst
index 0c00a0477..cd29f658c 100644
--- a/Test/C04funcdef.ztst
+++ b/Test/C04funcdef.ztst
@@ -515,6 +515,22 @@
 0:autoload with absolute path not cancelled by bare autoload
 >I have been loaded by explicit path.
 
+  (
+    fpath=(.)
+    print -n '['
+    for f in ${(s<>):-'x "#$^*$=|`<>?~,-!'}; do
+      # Test with both backslashes and single-quotes
+      print -r -- "${(q)f}_1() print -nr -- ${(q)f}" > ${f}_1
+      print -r -- "${(qq)f}_2() print -nr -- ${(qq)f}" > ${f}_2
+      autoload -Uz -- ${f}_1 ${f}_2
+      ${f}_1
+      ${f}_2
+    done
+    print ']'
+  )
+0:autoload with weird function names and ksh-style definitions
+>[xx  ""##$$^^**$$==||``<<>>??~~,,--!!]
+
   (
     FUNCNEST=0
     fn() { true; }




Messages sorted by: Reverse Date, Date, Thread, Author