Skip to content

Commit

Permalink
[oils] Check string->int overflow in flag parser, printf, etc.
Browse files Browse the repository at this point in the history
There are a couple more locations left.
  • Loading branch information
Andy C committed Oct 28, 2024
1 parent 2694f4b commit 239e008
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 12 deletions.
4 changes: 3 additions & 1 deletion builtin/printf_osh.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,9 @@ def _Percent(

if match.LooksLikeInteger(s):
# Note: spaces like ' -42 ' accepted and normalized
d = mops.FromStr(s)
ok, d = mops.FromStr2(s)
if not ok:
e_die("Integer too big: %s" % s, word_loc)

else:
# Check for 'a and "a
Expand Down
4 changes: 3 additions & 1 deletion frontend/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,9 @@ def __init__(self, name):
def _Value(self, arg, location):
# type: (str, loc_t) -> value_t
if match.LooksLikeInteger(arg):
i = mops.FromStr(arg)
ok, i = mops.FromStr2(arg)
if not ok:
e_usage('Integer too big: %s' % arg, location)
else:
e_usage(
'expected integer after %s, got %r' % ('-' + self.name, arg),
Expand Down
15 changes: 12 additions & 3 deletions osh/sh_expr_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,15 +316,24 @@ def _MaybeParseInt(s, blame_loc):

if id_ == Id.ShNumber_Dec:
# Normal base 10 integer.
return (True, mops.FromStr(s))
ok, big_int = mops.FromStr2(s)
if not ok:
e_die('Integer too big: %s' % s, blame_loc)
return (True, big_int)

elif id_ == Id.ShNumber_Oct:
# 0123, offset by 1
return (True, mops.FromStr(s[1:], 8))
ok, big_int = mops.FromStr2(s[1:], 8)
if not ok:
e_die('Octal integer too big: %s' % s, blame_loc)
return (True, big_int)

elif id_ == Id.ShNumber_Hex:
# 0xff, offset by 2
return (True, mops.FromStr(s[2:], 16))
ok, big_int = mops.FromStr2(s[2:], 16)
if not ok:
e_die('Hex integer too big: %s' % s, blame_loc)
return (True, big_int)

elif id_ == Id.ShNumber_BaseN:
b, digits = mylib.split_once(s, '#')
Expand Down
24 changes: 17 additions & 7 deletions test/runtime-errors.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1180,23 +1180,33 @@ test-int-overflow() {
local pos='18446744073709551616'
local neg='-18446744073709551616'

# TODO
return

if false; then
# frontend/args.py
_osh-error-1 "read -n $pos"
_osh-error-1 "read -n $neg"
_osh-error-2 "echo hi | read -n $pos"
_osh-error-2 "echo hi | read -n $neg"

# osh/sh_expr_eval.py
_osh-error-1 "s=$pos;"' echo $(( $s ))'
_osh-error-1 "s=$neg;"' echo $(( $s ))'
fi

# octal
local oct_pos='01234567012345670123456701234567'
local oct_neg="-$oct_pos"
_osh-error-1 "s=$oct_pos;"' echo $(( $s ))'
_osh-error-1 "s=$oct_neg;"' echo $(( $s ))' # treated as negation

# hex
local hex_pos='0x123456789abcdef0123456789'
local hex_neg="-$hex_pos"
_osh-error-1 "s=$hex_pos;"' echo $(( $s ))'
_osh-error-1 "s=$hex_neg;"' echo $(( $s ))' # treated as negation

# builtins
_osh-error-1 'printf %d'" $pos"
_osh-error-1 'printf %d'" $neg"

# TODO
return

_osh-error-1 "trap $pos ERR"
_osh-error-1 "trap $neg ERR"

Expand Down

0 comments on commit 239e008

Please sign in to comment.