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

Re: zsh -n doesn't grok associate array indexes?



On Mon, 10 Jan 2011 12:18:09 -0500
Rocky Bernstein <rocky.bernstein@xxxxxxxxx> wrote:
> I tried zsh -n to see how good a tool it might be for lint checking.
> Overall it works very well.
> 
> However I ran into a problem when using a string associative array
> index. Here's a sample run:
> 
> $ cat /tmp/zsh-bug.sh
> > typeset -A hash
> > hash['display']=5
> > echo ${hash['display']}
> > $ zsh /tmp/zsh-bug.sh
> > 5
> > $ zsh -n /tmp/zsh-bug.sh
> > /tmp/zsh-bug.sh:2: bad math expression: operand expected at
> > `'display'' /tmp/zsh-bug.sh:3: bad math expression: operand
> > expected at `'display'' $ zsh --version
> > zsh 4.3.10 (i686-pc-linux-gnu)

Certainly, a subscript is expected to be a math expression unless you've
explicitly told it the variable is an associative array.  However, given
that it's not executing the assignment I can see how you'd want it to
be otherwise here...  Actually, it looks like it was executing the
assignment, which must surely be wrong, too, since, as here, the
resulting operation may be nonsense.

I don't think anyone's ever sanity-checked NO_EXEC to this depth before,
let alone optimised it for useful checking, so you could run across
anything.  I've run across one myself:  we do globbing, which might
throw up a "no match" error.  Presumably doing any form of globbing is
pointless; I'm not sure how far to go into the code before it's not
worth it, but 'not very far' is the default answer, since the expression
hasn't been through previous expansion stages properly.

Index: Src/glob.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/glob.c,v
retrieving revision 1.74
diff -p -u -r1.74 glob.c
--- Src/glob.c	5 Dec 2010 21:07:48 -0000	1.74
+++ Src/glob.c	10 Jan 2011 18:18:18 -0000
@@ -1111,7 +1111,7 @@ zglob(LinkList list, LinkNode np, int no
     struct globdata saved;		/* saved glob state              */
     int nobareglob = !isset(BAREGLOBQUAL);
 
-    if (unset(GLOBOPT) || !haswilds(ostr)) {
+    if (unset(GLOBOPT) || !haswilds(ostr) || unset(EXECOPT)) {
 	if (!nountok)
 	    untokenize(ostr);
 	return;
Index: Src/params.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/params.c,v
retrieving revision 1.166
diff -p -u -r1.166 params.c
--- Src/params.c	21 Dec 2010 16:54:30 -0000	1.166
+++ Src/params.c	10 Jan 2011 18:18:18 -0000
@@ -1055,6 +1055,14 @@ getarg(char **str, int *inv, Value v, in
     zlong num = 1, beg = 0, r = 0, quote_arg = 0;
     Patprog pprog = NULL;
 
+    /*
+     * If in NO_EXEC mode, the parameters won't be set up
+     * properly, so there's no point even doing any sanity checking.
+     * Just return 0 now.
+     */
+    if (unset(EXECOPT))
+	return 0;
+
     ishash = (v->pm && PM_TYPE(v->pm->node.flags) == PM_HASHED);
     if (prevcharlen)
 	*prevcharlen = 1;
@@ -2230,6 +2238,8 @@ export_param(Param pm)
 mod_export void
 setstrvalue(Value v, char *val)
 {
+    if (unset(EXECOPT))
+	return;
     if (v->pm->node.flags & PM_READONLY) {
 	zerr("read-only variable: %s", v->pm->node.nam);
 	zsfree(val);
@@ -2361,6 +2371,8 @@ setnumvalue(Value v, mnumber val)
 {
     char buf[BDIGBUFSIZE], *p;
 
+    if (unset(EXECOPT))
+	return;
     if (v->pm->node.flags & PM_READONLY) {
 	zerr("read-only variable: %s", v->pm->node.nam);
 	return;
@@ -2398,6 +2410,8 @@ setnumvalue(Value v, mnumber val)
 mod_export void
 setarrvalue(Value v, char **val)
 {
+    if (unset(EXECOPT))
+	return;
     if (v->pm->node.flags & PM_READONLY) {
 	zerr("read-only variable: %s", v->pm->node.nam);
 	freearray(val);
@@ -2808,6 +2822,8 @@ sethparam(char *s, char **val)
 	errflag = 1;
 	return NULL;
     }
+    if (unset(EXECOPT))
+	return;
     queue_signals();
     if (!(v = fetchvalue(&vbuf, &s, 1, SCANPM_ASSIGNING)))
 	createparam(t, PM_HASHED);
@@ -2846,6 +2862,8 @@ setnparam(char *s, mnumber val)
 	errflag = 1;
 	return NULL;
     }
+    if (unset(EXECOPT))
+	return;
     queue_signals();
     ss = strchr(s, '[');
     v = getvalue(&vbuf, &s, 1);
Index: Test/E01options.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/E01options.ztst,v
retrieving revision 1.23
diff -p -u -r1.23 E01options.ztst
--- Test/E01options.ztst	22 Oct 2010 16:32:36 -0000	1.23
+++ Test/E01options.ztst	10 Jan 2011 18:18:18 -0000
@@ -344,6 +344,15 @@
 0:NO_EXEC option
 >before
 
+  (setopt noexec
+  typeset -A hash
+  hash['this is a string'])
+0:NO_EXEC option should not attempt to parse subscripts
+
+  (setopt noexec nomatch
+  echo *NonExistentFile*)
+0:NO_EXEC option should not do globbing
+
   setopt NO_eval_lineno
   eval 'print $LINENO'
   setopt eval_lineno

-- 
Peter Stephenson <pws@xxxxxxx>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom



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