DASH Shell discussions
 help / color / mirror / Atom feed
From: Michael Greenberg <michael@greenberg.science>
To: наб <nabijaczleweli@nabijaczleweli.xyz>, dash@vger.kernel.org
Subject: Re: Fwd: Bug#1017531: dash: for/while/if suppress errors from redirections with -e
Date: Thu, 18 Aug 2022 10:22:25 -0400	[thread overview]
Message-ID: <m2sfltskbi.fsf@greenberg.science> (raw)
In-Reply-To: <20220818114412.zeqv5auujpuvfskk@tarta.nabijaczleweli.xyz>

This looks like a serious bug... nice find!

I just checked my reference semantics shell (smoosh), and it fails this
test as well. Notably, smoosh passes the POSIX test suite---which means
that the POSIX folks are not properly testing for this behavior.

Also: what version of bash are you running? I suspect the fix to this in
bash is fairly recent.

$ bash --version
GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin17.7.0)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ bash -ec 'while :; do :; done < /ENOENT; echo uhoh'
bash: /ENOENT: No such file or directory
uhoh

$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
Copyright (C) 2007 Free Software Foundation, Inc.
$ /bin/bash -ec 'while :; do :; done < /ENOENT; echo uhoh'
/bin/bash: /ENOENT: No such file or directory
uhoh

Cheers,
Michael

On 2022-08-18 at 01:44:12 PM, наб wrote:

> Hi!
>
> Thought I'd forward this upstream, considering I already tested on
> current git, and it's pretty grave.
>
> https://bugs.debian.org/1017531, trimmed down a bit, follows:
>
> ----- Forwarded message from наб <nabijaczleweli@nabijaczleweli.xyz> -----
>
> Subject: Bug#1017531: dash: for/while/if suppress errors from redirections
>  with -e, POSIX violation
>
> Dear Maintainer,
>
> On current git (057cd650a4edd5856213d431a974ff35c6594489) and 0.5.11.5
> the following holds:
> -- >8 --
> $ ./src/dash -ec 'while :; do :; done < /ENOENT; echo uhoh'
> ./src/dash: 1: cannot open /ENOENT: No such file
> uhoh
> $ ./src/dash -ec 'for _ in :; do :; done < /ENOENT; echo uhoh'
> ./src/dash: 1: cannot open /ENOENT: No such file
> uhoh
> $ ./src/dash -ec 'if :; then :; fi < /ENOENT; echo uhoh'
> ./src/dash: 1: cannot open /ENOENT: No such file
> uhoh
> -- >8 --
>
> The correct output, as demonstrated by bash, is:
> -- >8 --
> $ bash -ec 'while :; do :; done < /ENOENT; echo uhoh'
> bash: line 1: /ENOENT: No such file or directory
> $ bash -ec 'for _ in :; do :; done < /ENOENT; echo uhoh'
> bash: line 1: /ENOENT: No such file or directory
> $ bash -ec 'if :; then :; fi < /ENOENT; echo uhoh'
> bash: line 1: /ENOENT: No such file or directory
> -- >8 --
>
> This is a POSIX violation, and quite a grave one at that:
> set -e is oft[1] used to guard against precisely this type of error!
>
> The same happens if set -e is executed.
>
> All quotes POSIX.1, Issue 7, TC2:
> sh, OPTIONS:
>   > The -a, -b, -C, -e, -f, -m, -n, -o option, -u, -v, and -x options
>   > are described as part of the set utility in Special Built-In
>   > Utilities. 
>
> set, DESCRIPTION, -e:
>   > When this option is on, when any command fails (for any of the
>   > reasons listed in Consequences of Shell Errors or by returning an
>   > exit status greater than zero), the shell immediately shall exit, as
>   > if by executing the exit special built-in utility with no arguments,
>   > with the following exceptions:
>   >
>   > 1. The failure of any individual command in a multi-command pipeline
>   >    shall not cause the shell to exit. Only the failure of the
>   >    pipeline itself shall be considered.
>   > 2. The -e setting shall be ignored when executing the compound list
>   >    following the while, until, if, or elif reserved word, a pipeline
>   >    beginning with the ! reserved word, or any command of an AND-OR
>   >    list other than the last.
>   > 3. If the exit status of a compound command other than a subshell
>   >    command was the result of a failure while -e was being ignored,
>   >    then -e shall not apply to this command.
>
> XCU, 2.9.4: Shell Command Language, Shell Commands, Compound Commands:
> The while Loop:
>   > The format of the while loop is as follows:
>   > 
>   > while compound-list-1
>   > do
>   >   compound-list-2
>   > done
> (until is equivalent).
> The if Conditional Construct: 
>   > The format for the if construct is as follows:
>   >
>   > if compound-list
>   > then
>   >   compound-list
>   > [elif compound-list
>   > then
>   >   compound-list] ...
>   > [else
>   >   compound-list]
>   > fi
>
> It follows, therefore, that
>   * Exception 1. does not apply as there is no pipeline
>   * Exception 2. does not apply, as the redirection does /not/ follow
>     "while" or "if" directly and is /not/ part of the conditional
> 	compound-list
>   * in the "for" case, there is no such provision, so this is likely not
>     a confusion w.r.t. the conditional compound-lists
>   * Exception 3. does not apply as -e was not being ignored while the
>     compound commands were being executed (indeed, the compound commands
>     do not run at all, as evidenced by the program terminating)
>
> [1]: https://salsa.debian.org/glibc-team/glibc/-/merge_requests/6#note_329899
> ----- End forwarded message -----
>
> Best,
> наб

  reply	other threads:[~2022-08-18 14:22 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-18 11:44 Fwd: Bug#1017531: dash: for/while/if suppress errors from redirections with -e наб
2022-08-18 14:22 ` Michael Greenberg [this message]
2022-08-18 15:02   ` наб
2022-12-07  3:59 ` [PATCH] eval: Check eflag after redirection error Herbert Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m2sfltskbi.fsf@greenberg.science \
    --to=michael@greenberg.science \
    --cc=dash@vger.kernel.org \
    --cc=nabijaczleweli@nabijaczleweli.xyz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox