zsh-workers
 help / color / mirror / code / Atom feed
* export "a=b"=~
@ 2017-03-08  8:50 Stephane Chazelas
  2017-03-08 13:23 ` Daniel Shahaf
  0 siblings, 1 reply; 4+ messages in thread
From: Stephane Chazelas @ 2017-03-08  8:50 UTC (permalink / raw)
  To: Zsh hackers list

Not that it's likely to ever be a concern, but I just noticed:

$ zsh -c 'export "a"=a=~; echo $a'
a=~
$ zsh -c 'export "a=a"=~; echo $a'
a=/home/chazelas
$ zsh -c 'export a=a=~; echo $a'
a=~

(5.1.1)

-- 
Stephane


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

* Re: export "a=b"=~
  2017-03-08  8:50 export "a=b"=~ Stephane Chazelas
@ 2017-03-08 13:23 ` Daniel Shahaf
  2017-03-08 15:44   ` Peter Stephenson
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Shahaf @ 2017-03-08 13:23 UTC (permalink / raw)
  To: Zsh hackers list

Stephane Chazelas wrote on Wed, Mar 08, 2017 at 08:50:00 +0000:
> Not that it's likely to ever be a concern, but I just noticed:
> 
> $ zsh -c 'export "a"=a=~; echo $a'
> a=~
> $ zsh -c 'export "a=a"=~; echo $a'
> a=/home/chazelas
> $ zsh -c 'export a=a=~; echo $a'
> a=~
> 
> (5.1.1)

[ I assume the point is that tilde expansion wasn't expected in the
second case. ]

Same behaviour in latest master.  This is because the MAGIC_EQUAL_SUBST
option, even when unset, implicitly applies to "export".  (The
declaration of "export" in builtins.c has the BINF_MAGICEQUALS flag
since before CVS.)

Should the behaviour be changed in 'emulate sh' / 'setopt posix*' mode?


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

* Re: export "a=b"=~
  2017-03-08 13:23 ` Daniel Shahaf
@ 2017-03-08 15:44   ` Peter Stephenson
  2017-03-08 22:30     ` Stephane Chazelas
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Stephenson @ 2017-03-08 15:44 UTC (permalink / raw)
  To: Zsh hackers list

On Wed, 8 Mar 2017 13:23:45 +0000
Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> Stephane Chazelas wrote on Wed, Mar 08, 2017 at 08:50:00 +0000:
> > Not that it's likely to ever be a concern, but I just noticed:
> > 
> > $ zsh -c 'export "a"=a=~; echo $a'
> > a=~
> > $ zsh -c 'export "a=a"=~; echo $a'
> > a=/home/chazelas
> > $ zsh -c 'export a=a=~; echo $a'
> > a=~
> > 
> > (5.1.1)
> 
> [ I assume the point is that tilde expansion wasn't expected in the
> second case. ]
> 
> Same behaviour in latest master.  This is because the MAGIC_EQUAL_SUBST
> option, even when unset, implicitly applies to "export".  (The
> declaration of "export" in builtins.c has the BINF_MAGICEQUALS flag
> since before CVS.)
> 
> Should the behaviour be changed in 'emulate sh' / 'setopt posix*' mode?

I think that flag is now largely redundant since these days the "~"
expansion is normally triggered by parsing the variable and argument
separately, in which case the older "magic" behaviour isn't useful.

Hence, regardless of compatibility mode, we should probably suppress
that flag in this case, leaving the fix-up magic behaviour for when we
encounter a builtin without recognising it as a keyword in the parser
(an unusual case where it's OK to make reasonable guesses and
compatibility with older zsh is probably the right answer).

So I think the following ought to work without any significant side
effects.  I've renamed the controlling variable for clarity; the older,
more general, name is now purely historical.

One extra thing: it seems likely that you don't want MAGIC_EQUAL_SUBST
behaviour *at all* in the case where you recognised the keyword,
i.e. even if the option is explicitly set, right?  So I've changed that,
too.  In other words,

setopt magicequalsubst
typeset "a=a"=~

*still* only assigns the value 'a=~'.  See comment I've added for the full
logic.

It would certainly be possible not to set magic_assign if the
POSIX_BUILTINS option is on, too, but that's now a very minor effect.

pws

diff --git a/Src/exec.c b/Src/exec.c
index 8b32246..ec415cf 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2658,7 +2658,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
     char *text;
     int save[10];
     int fil, dfil, is_cursh, do_exec = 0, redir_err = 0, i;
-    int nullexec = 0, assign = 0, forked = 0;
+    int nullexec = 0, magic_assign = 0, forked = 0;
     int is_shfunc = 0, is_builtin = 0, is_exec = 0, use_defpath = 0;
     /* Various flags to the command. */
     int cflags = 0, orig_cflags = 0, checked = 0, oautocont = -1;
@@ -2761,7 +2761,8 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 		/* autoload the builtin if necessary */
 		if (!(hn = resolvebuiltin(cmdarg, hn)))
 		    return;
-		assign = (hn->flags & BINF_MAGICEQUALS);
+		if (type != WC_TYPESET)
+		    magic_assign = (hn->flags & BINF_MAGICEQUALS);
 		break;
 	    }
 	    checked = 0;
@@ -2929,8 +2930,22 @@ execcmd_exec(Estate state, Execcmd_params eparams,
     if (noerrexit == 2 && !is_shfunc)
 	noerrexit = 0;
 
-    /* Do prefork substitutions */
-    esprefork = (assign || isset(MAGICEQUALSUBST)) ? PREFORK_TYPESET : 0;
+    /* Do prefork substitutions.
+     *
+     * Decide if we need "magic" handling of ~'s etc. in
+     * assignment-like arguments.
+     * - If magic_assign is set, we are using a builtin of the
+     *   tyepset family, but did not recognise this as a keyword,
+     *   so need guess-o-matic behaviour.
+     * - Otherwise, if we did recognise the keyword, we never need
+     *   guess-o-matic behaviour as the argument was properly parsed
+     *   as such.
+     * - Otherwise, use the behaviour specified by the MAGIC_EQUAL_SUBST
+     *   option.
+     */
+    esprefork = (magic_assign ||
+		 (isset(MAGICEQUALSUBST) && type != WC_TYPESET)) ?
+		 PREFORK_TYPESET : 0;
     if (args && eparams->htok)
 	prefork(args, esprefork, NULL);
 
@@ -3710,7 +3725,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 		     * Save if it's got "command" in front or it's
 		     * not a magic-equals assignment.
 		     */
-		    if ((cflags & (BINF_COMMAND|BINF_ASSIGN)) || !assign)
+		    if ((cflags & (BINF_COMMAND|BINF_ASSIGN)) || !magic_assign)
 			do_save = 1;
 		}
 		if (do_save && varspc)


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

* Re: export "a=b"=~
  2017-03-08 15:44   ` Peter Stephenson
@ 2017-03-08 22:30     ` Stephane Chazelas
  0 siblings, 0 replies; 4+ messages in thread
From: Stephane Chazelas @ 2017-03-08 22:30 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh hackers list

2017-03-08 15:44:28 +0000, Peter Stephenson:
[...]
> > Same behaviour in latest master.  This is because the MAGIC_EQUAL_SUBST
> > option, even when unset, implicitly applies to "export".  (The
> > declaration of "export" in builtins.c has the BINF_MAGICEQUALS flag
> > since before CVS.)
[...]
> So I think the following ought to work without any significant side
> effects.  I've renamed the controlling variable for clarity; the older,
> more general, name is now purely historical.
[...]

Some variations between shells:

$ ksh93 -c 'export a=~; echo $a; export "a"=~; echo $a; "export" a=~; echo $a; export a\=~; echo $a'
/home/chazelas
~
/home/chazelas
~
$ bash -c 'export a=~; echo $a; export "a"=~; echo $a; "export" a=~; echo $a; export a\=~; echo $a'
/home/chazelas
~
/home/chazelas
~
$ ARGV0=sh bash -c 'export a=~; echo $a; export "a"=~; echo $a; "export" a=~; echo $a; export a\=~; echo $a'
/home/chazelas
~
~
~
$ mksh -c 'export a=~; echo $a; export "a"=~; echo $a; "export" a=~; echo $a; export a\=~; echo $a'
/home/chazelas
/home/chazelas
/home/chazelas
~
$ dash -c 'export a=~; echo $a; export "a"=~; echo $a; "export" a=~; echo $a; export a\=~; echo $a'
~
~
~
~
$ yash -c 'export a=~; echo $a; export "a"=~; echo $a; "export" a=~; echo $a; export a\=~; echo $a'
~
~
~
~
$ zsh -c 'export a=~; echo $a; export "a"=~; echo $a; "export" a=~; echo $a; export a\=~; echo $a'
/home/chazelas
/home/chazelas
~
~
$ zsh -o magicequalsubst  -c 'export a=~; echo $a; export "a"=~; echo $a; "export" a=~; echo $a; export a\=~; echo $a'
/home/chazelas
/home/chazelas
/home/chazelas
~



After your patch:

$ ./Src/zsh -c 'export a=~; echo $a; export "a"=~; echo $a; "export" a=~; echo $a; export a\=~; echo $a'
/home/chazelas
~
~
~
$ ./Src/zsh -o magicequalsubst -c 'export a=~; echo $a; export "a"=~; echo $a; "export" a=~; echo $a; export a\=~; echo $a'
/home/chazelas
~
/home/chazelas
~


I can't say I have a strong opinion on what is best. I like
magic_equal_subst myself and I'm annoyed when ./configure
--prefix=~ doesn't work or sudo JAVA_HOME=~/jre... And I tend to
quote ~ when in doubt and don't want it to be expanded.

Note that in bash (when not in posix mode)

echo a=~

expands (so covers my sudo case above) but

echo --prefix=~

does not. What's on the left of the = has to look like a valid
literal unquoted bash variable name.

Started from:
https://askubuntu.com/questions/890415/why-couldnt-i-use-instead-of-home-username-when-giving-the-file-pat/890472#890472

-- 
Stephane


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

end of thread, other threads:[~2017-03-08 22:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-08  8:50 export "a=b"=~ Stephane Chazelas
2017-03-08 13:23 ` Daniel Shahaf
2017-03-08 15:44   ` Peter Stephenson
2017-03-08 22:30     ` Stephane Chazelas

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).