Re: Spaces trimmed from $* when assigned while IFS is unset [was: Unexpected word splitting on $* ...]

2017-10-04 Thread Martijn Dekker
Op 04-10-17 om 17:52 schreef Chet Ramey:
> It's interesting that other shells treat ${a:=b} as kind of like an
> assignment statement (word splitting) but not quite (tilde expansion).

Hmm...

v=~/bla
printf '%s\n' "$v"

outputs /Users/martijn/bla on all shells, so tilde expansion applies for
a simple assignment anyway.

And

unset -v v
v=${v:=~/bla}
printf '%s\n' "$v"

acts exactly the same.

This is all POSIXly correct, IIRC.

Of course, when ${v:=~/bla} is an unquoted expansion in a non-assignment
context, field splitting and pathname expansion apply to the expansion,
but not to the assignment itself, which is also perfectly logical:

[ -n "${ZSH_VERSION+s}" ] && emulate sh
unset -v v
touch /tmp/foo.bar /tmp/baz.bar
printf 'field: [%s]\n' ${v:=~/one ~/two /tmp/*.bar}
printf '  var: [%s]\n' "$v"

Output on bash, dash, FreeBSD sh, Busybox ash, yash, pdksh, mksh, ksh93,
zsh up to 5.0.8:

field: [/Users/martijn/one]
field: [~/two]
field: [/tmp/baz.bar]
field: [/tmp/foo.bar]
  var: [/Users/martijn/one ~/two /tmp/*.bar]

Output on zsh 5.1 and later, it seems to do tilde expansion after word
splitting instead of before -- which looks like a bug[*2], I'll take
that up there:

field: [/Users/martijn/one]
field: [/Users/martijn/two]
field: [/tmp/baz.bar]
field: [/tmp/foo.bar]
  var: [/Users/martijn/one ~/two /tmp/*.bar]

Output on bosh (schilytools) and NetBSD sh -- clearly a bug, it doesn't
do tilde expansion at all:

field: [~/one]
field: [~/two]
field: [/tmp/baz.bar]
field: [/tmp/foo.bar]
  var: [~/one ~/two /tmp/*.bar]

- Martijn

[*1]
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_01
[*2]
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06



Re: [BUG] Bash segfaults on an infinitely recursive funcion (resend)

2017-10-04 Thread Shlomi Fish
Hi all,

On Mon, 25 Sep 2017 13:38:01 -0500
Eric Blake  wrote:

> On 09/24/2017 12:53 PM, Shlomi Fish wrote:
> 
> > 
> > I see. Well, the general wisdom is that a program should not ever segfault,
> > but instead gracefully handle the error and exit.  
> 
> This is possible by installing a SIGSEGV handler that is able to
> gracefully exit the program when stack overflow is detected (although
> such a handler is EXTREMELY limited in what it is able to safely do); in
> fact, the GNU libsigsegv library helps in this task, and is used by some
> other applications (such as GNU m4 and GNU awk) that also can cause
> infinite recursion on poor user input. However, Chet is not obligated to
> use it (even though the idea has been mentioned on the list before).
> 
> > Perhaps implement a maximal
> > recursion depth like zsh does.  
> 
> Bash does, in the form of FUNCNEST, but you have to opt into it, as
> otherwise it would be an arbitrary limit, and arbitrary limits go
> against the GNU coding standards.
>

thanks for all the replies! All I can suggest is that FUNCNEST will have a
reasonable, but overridable and voidable default by default. Not sure if this
is an acceptable solution.

Regards,

Shlomi Fish 
> By the way, it is in general IMPOSSIBLE to write bash so that it can
> handle ALL possible bad user scripts and still remain responsive to
> further input.  Note that in my description of handling SIGSEGV above
> that I mention that it is only safe to gracefully turn what would
> otherwise be the default core dump into a useful error message - but
> bash STILL has to exit at that point, because you cannot guarantee what
> other resources (including malloc locks) might still be on the stack,
> where a longjmp back out to the main parsing loop may cause future
> deadlock if you do anything unsafe.  If you think you can make bash
> gracefully handle ALL possible bad inputs WITHOUT exiting or going into
> an infloop itself, then you are claiming that you have solved the
> Halting Problem, which any good computer scientist already knows has
> been proven to be undecidable.
> 



-- 
-
Shlomi Fish   http://www.shlomifish.org/
http://www.shlomifish.org/humour/bits/New-versions-of-the-GPL/

“If it’s not bloat, it’s not us.”, said Richard Stallman, the colourful head of
the GNU project, and started to sing the Free Software song.
— “The GNU Project Will Integrate GNU Guile into GNU coreutils”

Please reply to list if it's a mailing list post - http://shlom.in/reply .



Re: Spaces trimmed from $* when assigned while IFS is unset [was: Unexpected word splitting on $* ...]

2017-10-04 Thread Chet Ramey
On 9/26/17 11:50 PM, Martijn Dekker wrote:
> Op 20-06-17 om 02:13 schreef Kevin Brodsky:
>> When IFS is unset, unquoted $* undergoes word splitting as if IFS=' ',
>> and not the expected IFS=$' \t\n'.
> 
> Possibly related are the following two issues:

Thanks for the report. I'll fix these for the next devel branch push.

It's interesting that other shells treat ${a:=b} as kind of like an
assignment statement (word splitting) but not quite (tilde expansion).

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: [PATCH] Fix hang if $OLDPWD points to inaccessible directory

2017-10-04 Thread Eduardo A . Bustamante López
On Tue, Oct 03, 2017 at 10:29:08PM +0200, Mikulas Patocka wrote:
> If $OLDPWD points to a non-existing directory, 'cd -' will fail.
> But if we clear $OLDPWD, 'cd -' will fail too (with just different message).
[...]

I performed the following tests:


dualbus@ubuntu:~$ for sh in mksh ksh93 dash zsh posh bash; do echo $sh \| 
$(OLDPWD=/invalid $sh -c 'echo "$OLDPWD | "; cd -; echo " | $?"' 2>&1); done
mksh | /invalid | mksh: cd: /invalid: No such file or directory | 2
ksh93 | /invalid | ksh93: cd: /invalid: [No such file or directory] | 1
dash | /invalid | dash: 1: cd: can't cd to /invalid | 2
zsh | /home/dualbus | | 0
posh | /invalid | posh: cd: /invalid - No such file or directory | 1
bash | | bash: line 0: cd: OLDPWD not set | 1

dualbus@ubuntu:~$ for sh in mksh ksh93 dash zsh posh bash; do echo $sh \| 
$(OLDPWD=/tmp $sh -c 'echo "$OLDPWD | "; cd -; echo " | $?"' 2>&1); done
mksh | /tmp | /tmp | 0
ksh93 | /tmp | /tmp | 0
dash | /tmp | /tmp | 0
zsh | /home/dualbus | | 0
posh | /tmp | /tmp | 0
bash | /tmp | /tmp | 0


So:

- Bash is the only major shell that performs stat() on OLDPWD to see if it's
  going to import it from the environment or initialize it to an empty
  value.

- Zsh doesn't import OLDPWD from the environment (bash's old behavior)

- The rest of the shells (mksh, ATT ksh, dash, posh) import OLDPWD from
  the environment unconditionally.

- Mikulas already made the argument above of why this change wouldn't
  break existing scripts that rely on bash performing the stat().

- I don't see a way around this behavior using existing bash features.
  The value of OLDPWD can't be reset via BASH_ENV or other
  initialization mechanisms. Sure, `unset OLDPWD; program' might work,
  but I wouldn't call that a solution.


Given the above, I've changed my mind, and I think this patch should be
fine :-)