koalaman / shellcheck

ShellCheck, a static analysis tool for shell scripts
https://www.shellcheck.net
GNU General Public License v3.0
36.12k stars 1.77k forks source link

Ksh parser error with IPv4 validation regex #1254

Open andrewimeson opened 6 years ago

andrewimeson commented 6 years ago

For bugs

Here's a snippet or screenshot that shows the problem:


#!/bin/ksh
function is_ipv4 {
  ip=$1
  if [[ "$ip" == {1,3}(\d).{1,3}(\d).{1,3}(\d).{1,3}(\d) ]]; then
    OIFS=$IFS
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
        && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then
      return 0
    else
      return 1
    fi
  else
    return 1
  fi
}
is_ipv4 192.0.2.1 && echo "ipv4 validation #1 worked"
is_ipv4 192.0.2.256 || echo "ipv4 validation #2 worked"

Here's what shellcheck currently says:

In shellcheck-issue.ksh line 4:
  if [[ "$ip" == {1,3}(\d).{1,3}(\d).{1,3}(\d).{1,3}(\d) ]]; then
  ^-- SC1009: The mentioned parser error was in this if expression.
     ^-- SC1073: Couldn't parse this test expression.
                      ^-- SC1036: '(' is invalid here. Did you forget to escape it?
                      ^-- SC1072: Expected test to end here (don't wrap commands in []/[[]]). Fix any mentioned problems and try again.

Here's what I wanted or expected to see:

I don't think the expression is invalid, although I do not know regex well. The code works as expected.

$ ksh --version
  version         sh (AT&T Research) 93u+ 2012-08-01
$ ./shellcheck-issue.ksh
ipv4 validation #1 worked
ipv4 validation #2 worked
ngzhian commented 6 years ago

I think the parser doesn't recognize that that in ksh, == allows a pattern on the RHS. In bash, the RHS of a == is a string/variable. If you change == to =~, i think the parser will succeed, but you might have to tweak your regex to get what you want.