Skip to content

Commit

Permalink
Fix bug with ${var%''}.
Browse files Browse the repository at this point in the history
The issue is that we were computing s[:-0] when the suffix is empty.
Added an explicit check to fix it.

Addresses issue #291.

I also moved the spec tests around.  This bug was reported by Crestwave
as the "nested strip" case in spec/var-op-strip.
  • Loading branch information
Andy Chu committed May 1, 2019
1 parent 64fbb68 commit fa02622
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 92 deletions.
4 changes: 2 additions & 2 deletions osh/string_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,13 @@ def DoUnarySuffixOp(s, op, arg):
arg = glob_.GlobUnescape(arg)

if op.op_id in (Id.VOp1_Pound, Id.VOp1_DPound): # const prefix
if s.startswith(arg):
if arg and s.startswith(arg): # explicit check for non-empty arg
return s[len(arg):]
else:
return s

elif op.op_id in (Id.VOp1_Percent, Id.VOp1_DPercent): # const suffix
if s.endswith(arg):
if arg and s.endswith(arg): # need explicit check for non-empty arg
return s[:-len(arg)]
else:
return s
Expand Down
2 changes: 1 addition & 1 deletion osh/word_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ def _ApplyUnarySuffixOp(self, val, op):

if val.tag == value_e.Str:
s = string_ops.DoUnarySuffixOp(val.s, op, arg_val.s)
#log('%s %s -> %s', val.s, arg_val.s, s)
#log('%r %r -> %r', val.s, arg_val.s, s)
new_val = value.Str(s)
else: # val.tag == value_e.StrArray:
# ${a[@]#prefix} is VECTORIZED on arrays. Oil should have this too.
Expand Down
86 changes: 0 additions & 86 deletions spec/bugs.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,89 +20,3 @@ echo $a
## N-I dash/ash stdout-json: ""
## N-I dash/ash status: 2

#### Nested % and # operators (looks like a bug, reported by Crestwave)
var=$'\n'
argv.py "${var#?}"
argv.py "${var%''}"
argv.py "${var%"${var#?}"}"
var='a'
argv.py "${var#?}"
argv.py "${var%''}"
argv.py "${var%"${var#?}"}"
## STDOUT:
['']
['\n']
['\n']
['']
['a']
['a']
## END
## N-I dash STDOUT:
['\\n']
['$\\n']
['$']
['']
['a']
['a']
## END

#### # operator with single quoted arg (dash/ash and bash/mksh disagree, reported by Crestwave)
var=a
echo -${var#'a'}-
echo -"${var#'a'}"-
var="'a'"
echo -${var#'a'}-
echo -"${var#'a'}"-
## STDOUT:
--
--
-'a'-
-'a'-
## END
## OK dash/ash STDOUT:
--
-a-
-'a'-
--
## END

#### / operator with single quoted arg (causes syntax error in regex in OSH, reported by Crestwave)
var="++--''++--''"
echo no plus or minus "${var//[+-]}"
echo no plus or minus "${var//['+-']}"
## STDOUT:
no plus or minus ''''
no plus or minus ''''
## END
## status: 0
## OK osh STDOUT:
no plus or minus ''''
## END
## OK osh status: 1
## BUG ash STDOUT:
no plus or minus ''''
no plus or minus ++--++--
## END
## BUG ash status: 0
## N-I dash stdout-json: ""
## N-I dash status: 2

#### single quotes work inside character classes
x='a[[[---]]]b'
echo "${x//['[]']}"
## STDOUT:
a---b
## END
## BUG ash STDOUT:
a[[[---]]]b
## END
## N-I dash stdout-json: ""
## N-I dash status: 2
#### comparison: :- operator with single quoted arg
echo ${unset:-'a'}
echo "${unset:-'a'}"
## STDOUT:
a
'a'
## END
26 changes: 26 additions & 0 deletions spec/var-op-strip.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,29 @@ foo[]
[a]foo[]
foo[]
## END

#### Nested % and # operators (bug reported by Crestwave)
var=$'\n'
argv.py "${var#?}"
argv.py "${var%''}"
argv.py "${var%"${var#?}"}"
var='a'
argv.py "${var#?}"
argv.py "${var%''}"
argv.py "${var%"${var#?}"}"
## STDOUT:
['']
['\n']
['\n']
['']
['a']
['a']
## END
## N-I dash STDOUT:
['\\n']
['$\\n']
['$']
['']
['a']
['a']
## END
61 changes: 61 additions & 0 deletions spec/var-sub-quote.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,64 @@ a
abc
abc
## END
#### # operator with single quoted arg (dash/ash and bash/mksh disagree, reported by Crestwave)
var=a
echo -${var#'a'}-
echo -"${var#'a'}"-
var="'a'"
echo -${var#'a'}-
echo -"${var#'a'}"-
## STDOUT:
--
--
-'a'-
-'a'-
## END
## OK dash/ash STDOUT:
--
-a-
-'a'-
--
## END
#### / operator with single quoted arg (causes syntax error in regex in OSH, reported by Crestwave)
var="++--''++--''"
echo no plus or minus "${var//[+-]}"
echo no plus or minus "${var//['+-']}"
## STDOUT:
no plus or minus ''''
no plus or minus ''''
## END
## status: 0
## OK osh STDOUT:
no plus or minus ''''
## END
## OK osh status: 1
## BUG ash STDOUT:
no plus or minus ''''
no plus or minus ++--++--
## END
## BUG ash status: 0
## N-I dash stdout-json: ""
## N-I dash status: 2
#### single quotes work inside character classes
x='a[[[---]]]b'
echo "${x//['[]']}"
## STDOUT:
a---b
## END
## BUG ash STDOUT:
a[[[---]]]b
## END
## N-I dash stdout-json: ""
## N-I dash status: 2
#### comparison: :- operator with single quoted arg
echo ${unset:-'a'}
echo "${unset:-'a'}"
## STDOUT:
a
'a'
## END
5 changes: 2 additions & 3 deletions test/spec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,7 @@ osh-only() {

# Regress bugs
bugs() {
sh-spec spec/bugs.test.sh ${REF_SHELLS[@]} $ZSH $BUSYBOX_ASH $OSH_LIST "$@" \
--osh-failures-allowed 3
sh-spec spec/bugs.test.sh ${REF_SHELLS[@]} $ZSH $BUSYBOX_ASH $OSH_LIST "$@"
}

blog1() {
Expand Down Expand Up @@ -491,7 +490,7 @@ var-num() {
}

var-sub-quote() {
sh-spec spec/var-sub-quote.test.sh \
sh-spec spec/var-sub-quote.test.sh --osh-failures-allowed 2 \
${REF_SHELLS[@]} $OSH_LIST "$@"
}

Expand Down

0 comments on commit fa02622

Please sign in to comment.