zsh-workers
 help / color / mirror / code / Atom feed
* "bad substitution" error for ${a[b]}
@ 2015-07-15 20:03 Jason L Tibbitts III
  2015-07-16  0:09 ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Jason L Tibbitts III @ 2015-07-15 20:03 UTC (permalink / raw)
  To: zsh-workers

I'm trying to understand the following:

> echo '$a[b]' | zsh -fn

> echo '${a[b]}' | zsh -fn
zsh: bad substitution

Specifically, what's wrong with the second line?

I have vim doing basic syntax checking by running zsh -n and noticed
that it was complaining about the second line (obviously turned into a
minimal case) but not the first.  The script runs fine either way so I'm
not sure what's up.  Asked the folks on #zsh and they suggest I report
the issue here.

Thanks,

 - J<


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: "bad substitution" error for ${a[b]}
  2015-07-15 20:03 "bad substitution" error for ${a[b]} Jason L Tibbitts III
@ 2015-07-16  0:09 ` Bart Schaefer
  2015-07-16  8:30   ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2015-07-16  0:09 UTC (permalink / raw)
  To: zsh-workers; +Cc: Jason L Tibbitts III

On Jul 15,  3:03pm, Jason L Tibbitts III wrote:
} Subject: "bad substitution" error for ${a[b]}
}
} I'm trying to understand the following:
} 
} > echo '$a[b]' | zsh -fn
} 
} > echo '${a[b]}' | zsh -fn
} zsh: bad substitution
} 
} Specifically, what's wrong with the second line?

Nothing; zsh is confused by trying to parse an interpreted language
without performing any real interpretation.


With NO_EXEC set, something goes wrong in getindex() called from subst.c
line 2433 (in the current git revision) such that the pointer to "s" is
not advanced past the subscript expression.  Less specifically, zsh sees
a '[' where it expects to find a '}' and complains.

Amusingly the problem seems to be in getarg() right here:

   1118     /*
   1119      * If in NO_EXEC mode, the parameters won't be set up
   1120      * properly, so there's no point even doing any sanity checking.
   1121      * Just return 0 now.
   1122      */
   1123     if (unset(EXECOPT))
   1124         return 0;

This is a bit of a conundrum.  The subscript expression can't be parsed
correctly without knowing whether it is subscripting a plain array or an
associative array, but in NO_EXEC mode the variable is neither set nor
declared so the type can't be known.

When there are no braces, NO_EXEC treats $a[b] as ${a}'[b]' and silently
ignores the whole issue.  Leaving aside that particular weirdness, the
following seems to do the trick; objections?  Grotesque nested expansion
cases that are going to go horribly awry?


diff --git a/Src/params.c b/Src/params.c
index 3b75735..7d0c852 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -1116,14 +1116,12 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
     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 in NO_EXEC mode, the parameters won't be set up properly,
+     * so just pretend everything is a hash for subscript parsing
      */
-    if (unset(EXECOPT))
-	return 0;
 
-    ishash = (v->pm && PM_TYPE(v->pm->node.flags) == PM_HASHED);
+    ishash = (unset(EXECOPT) ||
+	      (v->pm && PM_TYPE(v->pm->node.flags) == PM_HASHED));
     if (prevcharlen)
 	*prevcharlen = 1;
     if (nextcharlen)
@@ -1278,8 +1276,18 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
     }
     if (!c)
 	return 0;
-    s = dupstrpfx(s, t - s);
     *str = tt = t;
+
+    /*
+     * If in NO_EXEC mode, the parameters won't be set up properly,
+     * so there's no additional sanity checking we can do.
+     * Just return 0 now.
+     */
+    if (unset(EXECOPT))
+	return 0;
+
+    s = dupstrpfx(s, t - s);
+
     /* If we're NOT reverse subscripting, strip the inull()s so brackets *
      * are not backslashed after parsestr().  Otherwise leave them alone *
      * so that the brackets will be escaped when we patcompile() or when *

-- 
Barton E. Schaefer


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: "bad substitution" error for ${a[b]}
  2015-07-16  0:09 ` Bart Schaefer
@ 2015-07-16  8:30   ` Peter Stephenson
  2015-07-16 20:47     ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2015-07-16  8:30 UTC (permalink / raw)
  To: zsh-workers

On Wed, 15 Jul 2015 17:09:44 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> +     * If in NO_EXEC mode, the parameters won't be set up properly,
> +     * so just pretend everything is a hash for subscript parsing

THat seems a reasonable approach, though we could do with taking some of
the parameter substitution test cases and feeding them through NO_EXEC.

pws


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: "bad substitution" error for ${a[b]}
  2015-07-16  8:30   ` Peter Stephenson
@ 2015-07-16 20:47     ` Bart Schaefer
  2015-07-17 19:30       ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2015-07-16 20:47 UTC (permalink / raw)
  To: zsh-workers

On Jul 16,  9:30am, Peter Stephenson wrote:
}
} [...] we could do with taking some of the parameter substitution test
} cases and feeding them through NO_EXEC.

Any suggestions which ones?  The only thing that should have changed
with 35799 is subscript handling.

The following caes all work, but of course "work" means "do nothing at
all" -- so I guess the point is just to assert that there are no errors?


diff --git a/Test/E01options.ztst b/Test/E01options.ztst
index ca3f06c..16279b8 100644
--- a/Test/E01options.ztst
+++ b/Test/E01options.ztst
@@ -362,6 +362,20 @@
   echo ${unset_var?Not an error})
 0:NO_EXEC should not test for unset variables
 
+  (setopt noexec
+  : ${${string%[aeiou]*}/(#m)?(#e)/${(U)MATCH}}  Rule 1
+  : ${array[4,5][1][2,3]}                        Rule 2
+  : ${${(P)foo[1,6]}[1,3]}                       Rule 3
+  : "${${(@)array}[1,2]}"                        Rule 5
+  : "${(@)${(@)array}[1,2]#?}"                   Rule 6
+  : ${(el.20..X.)${bar}}                         Rule 11 success case)
+0:NO_EXEC handles parameter substitution examples
+
+  (setopt noexec
+  : ${(el.20..X.)$bar}                           Rule 11 failure case)
+1:NO_EXEC does recognize bad substitution syntax
+*?* bad substitution
+
   setopt NO_eval_lineno
   eval 'print $LINENO'
   setopt eval_lineno


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: "bad substitution" error for ${a[b]}
  2015-07-16 20:47     ` Bart Schaefer
@ 2015-07-17 19:30       ` Peter Stephenson
  0 siblings, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2015-07-17 19:30 UTC (permalink / raw)
  To: Bart Schaefer, zsh-workers

On Thu, 16 Jul 2015 13:47:02 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Jul 16,  9:30am, Peter Stephenson wrote:
> }
> } [...] we could do with taking some of the parameter substitution test
> } cases and feeding them through NO_EXEC.
> 
> Any suggestions which ones?  The only thing that should have changed
> with 35799 is subscript handling.
> 
> The following caes all work, but of course "work" means "do nothing at
> all" -- so I guess the point is just to assert that there are no errors?

Yes, just a random selection including subscripts to have a bit of
confidence it's roughly in order.  That looks reasonable.

Thanks
pws


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-07-17 19:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-15 20:03 "bad substitution" error for ${a[b]} Jason L Tibbitts III
2015-07-16  0:09 ` Bart Schaefer
2015-07-16  8:30   ` Peter Stephenson
2015-07-16 20:47     ` Bart Schaefer
2015-07-17 19:30       ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).