#1035679 zsh: can misprocess continue in a loop

Package:
zsh
Source:
zsh
Description:
shell with lots of features
Submitter:
brian m. carlson
Date:
2023-05-28 14:15:03 UTC
Severity:
normal
Tags:
#1035679#5
Date:
2023-05-07 17:18:05 UTC
From:
To:
If a continue occurs in an && chain inside a loop, the continue is not
effective.  For example, if you save the following as foo.sh:
----
msg=unset
for x in 1 2 3 4 5; do
  continue && msg=set && print Not executed
  print Not executed, neither.
done
echo $msg
----

The output should be "unset", but zsh prints "set":
---- $ bash foo.sh unset $ dash foo.sh unset $ zsh foo.sh set ---- This breaks the Git testsuite under zsh's sh mode, which was formerly passing. There's a patch upstream at https://github.com/zsh-users/zsh/commit/12e5db145b098a62ff11b88eea26f473ea2ecdcf. It would be great if this could be backported to zsh in Debian, since the release cycle tends to be long and it prevents the shell from being effectively used as a POSIX sh.
#1035679#10
Date:
2023-05-08 00:58:24 UTC
From:
To:
Hi Brian,

brian m. carlson wrote:

Thanks for the bug report.

Hmmm, actually, your example code shows "set" for me even without sh
emulation mode:

  → zsh continue.sh
  set
  → zsh --emulate sh continue.sh
  set

When was "formerly", i.e. in which package or upstream version?

Actually the lines changed in the upstream fix were last changed in
the year 2000. And I was able to reproduce this issue in zsh 5.0.7
from Debian 8 Jessie (now ELTS).

So it's in there for probably at least 23 years and clearly not a
recent regression — if it's a regression at all. (I kinda doubt it
with my current state of knowledge.)

So I suspect that the Git testsuite only recently started to use
"continue &&" recently?

Then actually only find only a single occurence of "continue &&" (which
is not "--continue &&" or suchlike) and that one seems to be a comment:

  t/t3418-rebase-continue.sh:     : skip and continue &&

And the test which contains that (suspected) comment was added in 2018
in commit d5bc6f292ab0a1715ff021f5854ac5a81c2b88b0.

Can do, but for Bookworm this is likely too late as we're now in the
last stage of the freeze with the release planned for in one month and
this change clearly changes a longtime zsh behaviour.

Well, 5.9 is out for quite a while already. So I think we can expect a
new release before the the Debian 13 release. ;-)

But yeah, I think we can cherry-pick this from upstream after the
Bookworm release.

Well, zsh's POSIX mode is officially declared as being incomplete and
it's IIRC also not recommended to actually use it or at least not rely
on it.

Also upstream's statements like "probably ought to be regarded as a
bug" and "However, it's not logically wrong, either." sound as if it's
more a bug by goodwill, not by conviction.

And I must admit that "continue &&" as bash, ksh and all others
process it IMHO makes less sense than how zsh used to do it. That's
probably what upstream meant with "it's not logically wrong". But
let's follow upstream here. :-)

		Regards, Axel

#1035679#19
Date:
2023-05-28 14:05:58 UTC
From:
To:
Correct.  The Git testsuite only runs under sh mode, not zsh mode, but
it affects all modes.

Git 2.25.  It may be that Git has changed the testsuite to make use of
that syntax between now and then, but as of that revision, it passed.

Great, I appreciate that.

zsh should be able to run as a POSIX sh.  The reason that we only
support sh mode in Git is that we rely on every command in a pipeline
being run in a subshell, since we only recently introduced the use of
`local` in the shell and otherwise our variables get messed up.