mvdan / sh

A shell parser, formatter, and interpreter with bash support; includes shfmt
https://pkg.go.dev/mvdan.cc/sh/v3
BSD 3-Clause "New" or "Revised" License
7.16k stars 338 forks source link

interp: let arithmetic expression is not properly evaluated when expression is enclosed in string #754

Open riacataquian opened 2 years ago

riacataquian commented 2 years ago

Given let.sh as the input file:

#!/bin/bash

let "varone=1" "vartwo=++varone"; echo $varone, $vartwo
let "myvar=16 << 2"; echo $myvar

let varone=1 vartwo=++varone; echo $varone, $vartwo
let myvar="16 << 2"; echo $myvar

On bash:

$ ./let.sh
2, 2
64
2, 2
64

Versus on gosh:

$ gosh let.sh
,

2, 2
0

Gosh correctly evaluated let varone=1 vartwo=++varone but not let myvar="16 << 2".

mvdan commented 2 years ago

This is similar to https://github.com/mvdan/sh/issues/743, but applied to arithmetic expressions rather than assignment expressions.

I think it makes sense to do this kind of "second pass parsing", where we do an arithmetic expression parse on the expanded string field while interpreting. We can't pretend to only support parsing statically, because then we lose too much compatibility with sh/bash, as you point out.

I think my only worry would be the performance; we don't want to be re-parsing absolutely every string that goes through the arithmetic expression interpreter. One way would be to only do this re-parsing if a field was a quoted string.