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

Re: PATCH: dynamic named directories



On Fri, 26 Sep 2008 14:56:32 +0200
"Mikael Magnusson" <mikachu@xxxxxxxxx> wrote:
> 2008/9/26 Mikael Magnusson <mikachu@xxxxxxxxx>:
> > 2008/9/25 Peter Stephenson <pws@xxxxxxx>:
> >
> > Here's line broken backtrace of the week
> >
> > (gdb) run
> > Starting program: /usr/local/bin/zsh -f
> > fartmonstret% zsh_directory_name() {}
> > fartmonstret% cd ~[a b]
> 
> Well, maybe the space is a bit of a red herring there. 'cd ~[a'
> appears to give more or less the same result.

Oops.  Thanks.  The problem is the search for "]".  If that was
attempted but the name substitution failed, the pointer used in the next
test was messed up.  In the first case, the failure is after the call to
zsh_directory_name, in the second before since the search for "]"
itself failed.  (You'd have found the first case didn't crash if there
was already a value for $reply, which would have been used as the
directory---you do have to stick to the rules to get it to work
properly, although obviously it shouldn't crash.)

I've also spotted that the substitution code requires static named
directories to have the same set of chararacters as user names, whether
or not they are user names.  So (i) this should be documented (ii) hash
-d should check when defining static names for directories since it's
pointless and confusing if they can be defined but can't be used (there
isn't room to list the valid characters in the error message).

It's not obvious that this limitation is necessary, however.  It
obviously comes from when named directories could only be user names or
parameters; with "hash -d" we could in principle relax it.  However,
I don't think there's any good reason to use a wider name space and
there's every possibility of confusion with people wondering why tilde
squiggle squiggle squiggle slash doesn't do quite what they want.

Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.92
diff -u -r1.92 expn.yo
--- Doc/Zsh/expn.yo	26 Sep 2008 09:11:28 -0000	1.92
+++ Doc/Zsh/expn.yo	27 Sep 2008 19:29:23 -0000
@@ -1375,13 +1375,16 @@
 cindex(directories, named, static)
 cindex(named directories, static)
 cindex(static named directories)
-A `tt(~)' followed by anything not already covered is looked up as a
+A `tt(~)' followed by anything not already covered consisting
+of any number of alphanumeric characters or underscore (`tt(_)'),
+hyphen (`tt(-)'), or dot (`tt(.)') is looked up as a
 named directory, and replaced by the value of that named directory if found.
 Named directories are typically home directories for users on the system.
 They may also be defined if the text after the `tt(~)' is the name
 of a string shell parameter whose value begins with a `tt(/)'.
 Note that trailing slashes will be removed from the path to the directory
 (though the original parameter is not modified).
+
 It is also possible to define directory names using the tt(-d) option to the
 tt(hash) builtin.
 
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.208
diff -u -r1.208 builtin.c
--- Src/builtin.c	23 Sep 2008 08:42:01 -0000	1.208
+++ Src/builtin.c	27 Sep 2008 19:29:26 -0000
@@ -3262,9 +3262,19 @@
 		/* The argument is of the form foo=bar, *
 		 * so define an entry for the table.    */
 		if(OPT_ISSET(ops,'d')) {
-		    Nameddir nd = hn = zshcalloc(sizeof *nd);
-		    nd->node.flags = 0;
-		    nd->dir = ztrdup(asg->value);
+		    /* shouldn't return NULL if asg->name is not NULL */
+		    if (*itype_end(asg->name, IUSER, 0)) {
+			zwarnnam(name,
+				 "invalid character in directory name: %s",
+				 asg->name);
+			returnval = 1;
+			argv++;
+			continue;
+		    } else {
+			Nameddir nd = hn = zshcalloc(sizeof *nd);
+			nd->node.flags = 0;
+			nd->dir = ztrdup(asg->value);
+		    }
 		} else {
 		    Cmdnam cn = hn = zshcalloc(sizeof *cn);
 		    cn->node.flags = HASHED;
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.87
diff -u -r1.87 subst.c
--- Src/subst.c	26 Sep 2008 09:11:30 -0000	1.87
+++ Src/subst.c	27 Sep 2008 19:29:27 -0000
@@ -529,7 +529,7 @@
 
     if (*str == Tilde && str[1] != '=' && str[1] != Equals) {
 	Shfunc dirfunc;
-	char *ptr, *tmp, *res;
+	char *ptr, *tmp, *res, *ptr2;
 	int val;
 
 	val = zstrtol(str + 1, &ptr, 10);
@@ -544,14 +544,14 @@
 	    return 1;
 	} else if (str[1] == Inbrack &&
 		   (dirfunc = getshfunc("zsh_directory_name")) &&
-		   (ptr = strchr(str+2, Outbrack))) {
+		   (ptr2 = strchr(str+2, Outbrack))) {
 	    char **arr;
-	    untokenize(tmp = dupstrpfx(str+2, ptr - (str+2)));
+	    untokenize(tmp = dupstrpfx(str+2, ptr2 - (str+2)));
 	    remnulargs(tmp);
 	    arr = subst_string_by_func(dirfunc, "n", tmp);
 	    res = arr ? *arr : NULL;
 	    if (res) {
-		*namptr = dyncat(res, ptr+1);
+		*namptr = dyncat(res, ptr2+1);
 		return 1;
 	    }
 	    if (isset(NOMATCH))


-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



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