Skip to contentSkip to conversation

dash doesn't report syntax error when it should on stray "fi"

BUG Stefano Lattarini 4 participants 9 messages Apr 23, 2012 – Apr 24, 2012

lore
Share & tools
lore
#0 lore raw

How to reproduce:

  $ dash -c ':; fi'; echo stat = $?
  stat = 0

Behaviour of other shells:

  $ bash-4.1 -c ':; fi'; echo stat = $?  # Bash 4.1.5
  bash-4.1: -c: line 0: syntax error near unexpected token `fi'
  bash-4.1: -c: line 0: `:; fi'
  stat = 1
  $ bash-3.2 -c ':; fi'; echo stat = $? # Bash 3.2.0
  bash-3.2: -c: line 0: syntax error near unexpected token `fi'
  bash-3.2: -c: line 0: `:; fi'
  stat = 2
  $ ksh -c ':; fi'; echo stat = $? # AT&T Ksh
  ksh: syntax error at line 1: `fi' unexpected
  stat = 3
  $ pdksh -c ':; fi'; echo stat = $? # Public Domain Ksh, version 5.2.14
  pdksh: syntax error: `fi' unexpected
  stat = 1
  $ zsh -c ':; fi'; echo stat = $?  # Zsh 4.3.12
  zsh:1: parse error near `fi'
  stat = 1

Version information:

  $ dpkg -l dash
  ii   dash   0.5.5.1-7.4   POSIX-compliant shell

Regards,
Stefano

#1 lore raw

Hi Stefano,

Quoted 4 lines · Stefano Lattarini

How to reproduce:

  $ dash -c ':; fi'; echo stat = $?
  stat = 0

Since this doesn't affect conforming scripts, I suspect it falls squarely within the "patches welcome as long as they don't make dash bigger" category.

Thanks for finding it.

Sincerely,
Jonathan

#2 lore raw

Hi Jonathan, thanks for the quick reply.

Quoted 11 lines · Jonathan Nieder

Hi Stefano,

Quoted 4 lines · Stefano Lattarini

How to reproduce:

  $ dash -c ':; fi'; echo stat = $?
  stat = 0

Since this doesn't affect conforming scripts,

True, it it makes "dash -n" less useful (not that I deeply care, just pointing it out).

Quoted 7 lines

I suspect it falls squarely within the "patches welcome as long as they don't make dash bigger" category.

Thanks for finding it.

Sincerely,
Jonathan

Thanks,
Stefano

#3 lore raw
In reply to Jonathan Nieder
Quoted 4 lines · Jonathan Nieder

Hi Stefano,

Stefano Lattarini wrote:

Quoted 8 lines
Quoted 4 lines

How to reproduce:

  $ dash -c ':; fi'; echo stat = $?
  stat = 0

Since this doesn't affect conforming scripts, I suspect it falls squarely within the "patches welcome as long as they don't make dash bigger" category.

What are `conforming scripts'? Scripts without syntax errors?

Signature · 3 lines
``The lyf so short, the craft so long to lerne.'' - Chaucer
		 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU    [email protected]    http://cnswww.cns.cwru.edu/~chet/
#4 lore raw
Quoted 1 line · Chet Ramey

What are `conforming scripts'? Scripts without syntax errors?

I meant "conforming POSIX applications".

A patch for this might even be welcome if it makes dash bigger, if that's what you're wondering.

#5 lore raw
Quoted 8 lines · Jonathan Nieder
Quoted 1 line · Chet Ramey

What are `conforming scripts'? Scripts without syntax errors?

I meant "conforming POSIX applications".

A patch for this might even be welcome if it makes dash bigger, if that's what you're wondering.

The way I read 2.10.2, Posix requires that the "fi" resolve to the reserved word `fi' in this case, since it's in a position where a command name is expected (Rule 1, [Command Name]). I would think that would make it a syntax error in any application, conforming or not.

Chet

Signature · 3 lines
``The lyf so short, the craft so long to lerne.'' - Chaucer
		 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU    [email protected]    http://cnswww.cns.cwru.edu/~chet/
#6 lore raw
Quoted 4 lines · Chet Ramey

The way I read 2.10.2, Posix requires that the "fi" resolve to the reserved word `fi' in this case, since it's in a position where a command name is expected (Rule 1, [Command Name]). I would think that would make it a syntax error in any application, conforming or not.

Yes, I think you're right.

For some reason I thought that using reserved words in ways not permitted by the grammar produced undefined behavior, to support shells with extensions like the arithmetic "for". But now that I read more closely, it looks like "function", "[[", "]]", and "select" produce unspecified behavior but everything else is pretty well specified. Thanks for clarifying.

#7 lore raw
Quoted 7 lines · Jonathan Nieder
Quoted 4 lines · Chet Ramey

The way I read 2.10.2, Posix requires that the "fi" resolve to the reserved word `fi' in this case, since it's in a position where a command name is expected (Rule 1, [Command Name]). I would think that would make it a syntax error in any application, conforming or not.

Quoted 8 lines

Yes, I think you're right.

For some reason I thought that using reserved words in ways not permitted by the grammar produced undefined behavior, to support shells with extensions like the arithmetic "for". But now that I read more closely, it looks like "function", "[[", "]]", and "select" produce unspecified behavior but everything else is pretty well specified. Thanks for clarifying.

In what way does a lone "fi" differ from constructions like the below, which do not match the POSIX grammar but are accepted by some subset of shells that attempt to comply to POSIX:

case x in (esac) ;; esac

for i; do echo "$i"; done

for i;
do echo "$i"; done

for i { echo "$i"; }

for ((i = 0; i < 10; i += 1)) do echo "$i"; done

f() :

The only difference seems to be that the lone "fi" is somehow "wrong" while the above are not "wrong". That's too vague for a specification.

Unfortunately, the XCU volume is very thin on constraints (as found, for example, in the C standard). Many ways to do things "wrong" are instead left open for implementation extensions. In practice, many such extensions exist.

That said, rejecting the lone "fi" is still a quality of implementation issue, particularly because dash's current behaviour is poorly defined. I fixed it in FreeBSD a while ago (9.0 has the fix).

In making this change, a testsuite is very useful to guard against bugs and to ensure no cases are missed, but latent bugs in shell scripts may still cause annoyance. If there is an error in a command substitution that is normally not executed, most shells (except ash derivatives) will not notice this.

For example, FreeBSD 9.0's sh is one of the few shells that detects the error in:

if false; then fi; fi

Signature · 1 line
Jilles Tjoelker
#8 lore raw
In reply to Jonathan Nieder

Hi Jonathan, Chet.

Quoted 9 lines · Jonathan Nieder
Quoted 1 line · Chet Ramey

What are `conforming scripts'? Scripts without syntax errors?

I meant "conforming POSIX applications".

A patch for this might even be welcome if it makes dash bigger, if that's what you're wondering.

I have no patch, but a little more information that might help anyone who volunteers to write one:

  $ nl=$'\n'
  $ dash -c ":$nl fi" && echo NOERR
  dash: Syntax error: "fi" unexpected
  $ dash -c ":;$nl fi" && echo NOERR
  dash: Syntax error: "fi" unexpected
  $ dash -c ":&$nl fi" && echo NOERR
  dash: Syntax error: "fi" unexpected
  $ dash -c ": && fi" && echo NOERR
  dash: Syntax error: "fi" unexpected

The problem seems to only be present when a stray "fi" comes after a '&' or ';' -- see:

  $ dash -c ":; fi" && echo NOERR
  NOERR
  dash -c ":& fi" && echo NOERR
  NOERR

The same goes for other loops/conditionals terminators:

  $ dash -c ":; done" && echo NOERR
  NOERR
  $ dash -c ":; esac" && echo NOERR
  NOERR
  $ dash -c ":& elif" && echo NOERR
  NOERR

HTH,
Stefano