Skip to content

Commit

Permalink
Merge pull request #983 from Zilliqa/fix_int_lit_release
Browse files Browse the repository at this point in the history
Fix parsing of integers with leading 0s (#982)
  • Loading branch information
AmritKumar committed Apr 21, 2021
2 parents 59281f2 + c2ef23a commit 29ea7b2
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 8 deletions.
48 changes: 40 additions & 8 deletions src/base/Literal.ml
Expand Up @@ -408,16 +408,48 @@ module MkLiteral (T : ScillaType) = struct
let validate_int_string pt x =
let open PrimType in
let open String in
(* Sanitise x before feeding it to of_string. Remove unnecessary sign and leading 0s.
A legal integer matches the regexp [+-]?0*(0|([1-9][0-9]))
"-0" is a special case, so we treat a leading '-' sign separately:
Leading '-': A legal integer matches the regexp -0*(0|([1-9][0-9])).
Remove the 0* part of the string.
Then check if the result is "-0".
If it is, then remove the leading '-'. Otherwise we have the result.
No leading '-': A legal integer matches the regexp +?0*(0|([1-9][0-9])).
Remove the 0* part of the string as well as the '+' sign if it's there.
*)
let x_sanitised =
if String.(sub x ~pos:0 ~len:1 = "-") then
(* Remove unnecessary leading 0s after the sign *)
let x_without_leading_0s =
Str.replace_first (Str.regexp "^-0*\\([0-9]+\\)$") "-\\1" x
in
(* The result may now be -0. If so, then remove the - *)
Str.replace_first (Str.regexp "^-0$") "0" x_without_leading_0s
else
(* Remove unnecessary leading 0s and + sign if it's there *)
Str.replace_first (Str.regexp "^\\+?0*\\([0-9]+\\)$") "\\1" x
in
try
match pt with
| Int_typ Bits32 -> Int32.to_string (Int32.of_string x) = x
| Int_typ Bits64 -> Int64.to_string (Int64.of_string x) = x
| Int_typ Bits128 -> Int128.to_string (Int128.of_string x) = x
| Int_typ Bits256 -> Int256.to_string (Int256.of_string x) = x
| Uint_typ Bits32 -> Uint32.to_string (Uint32.of_string x) = x
| Uint_typ Bits64 -> Uint64.to_string (Uint64.of_string x) = x
| Uint_typ Bits128 -> Uint128.to_string (Uint128.of_string x) = x
| Uint_typ Bits256 -> Uint256.to_string (Uint256.of_string x) = x
| Int_typ Bits32 ->
Int32.to_string (Int32.of_string x_sanitised) = x_sanitised
| Int_typ Bits64 ->
Int64.to_string (Int64.of_string x_sanitised) = x_sanitised
| Int_typ Bits128 ->
Int128.to_string (Int128.of_string x_sanitised) = x_sanitised
| Int_typ Bits256 ->
Int256.to_string (Int256.of_string x_sanitised) = x_sanitised
| Uint_typ Bits32 ->
Uint32.to_string (Uint32.of_string x_sanitised) = x_sanitised
| Uint_typ Bits64 ->
Uint64.to_string (Uint64.of_string x_sanitised) = x_sanitised
| Uint_typ Bits128 ->
Uint128.to_string (Uint128.of_string x_sanitised) = x_sanitised
| Uint_typ Bits256 ->
Uint256.to_string (Uint256.of_string x_sanitised) = x_sanitised
| _ -> false
with _ -> false

Expand Down
1 change: 1 addition & 0 deletions tests/eval/good/Good.ml
Expand Up @@ -154,6 +154,7 @@ let explist =
"endian_test64.scilexp";
"endian_test128.scilexp";
"endian_test256.scilexp";
"int_lits.scilexp";
]

module Tests = Scilla_test.Util.DiffBasedTests (struct
Expand Down
66 changes: 66 additions & 0 deletions tests/eval/good/gold/int_lits.scilexp.gold
@@ -0,0 +1,66 @@
(True),
{ [cn3 -> (Int32 0)],
[cn2 -> (Int32 12)],
[cn1 -> (Int32 12)],
[res_c9 -> (Some (Int32 0))],
[c9 -> (String "0")],
[res_c8 -> (None)],
[c8 -> (String "")],
[res_c7 -> (None)],
[c7 -> (String "00001Hello")],
[res_c6 -> (None)],
[c6 -> (String "000000Hello")],
[res_c5 -> (None)],
[c5 -> (String "0Hello")],
[res_c4 -> (None)],
[c4 -> (String "Hello")],
[res_c3 -> (Some (Int32 0))],
[c3 -> (String "00000")],
[res_c2 -> (Some (Int32 123))],
[c2 -> (String "00000123")],
[res_c1 -> (Some (Int32 123))],
[c1 -> (String "123")],
[bn3 -> (Int32 0)],
[bn2 -> (Int32 -12)],
[bn1 -> (Int32 -12)],
[res_b10 -> (None)],
[b10 -> (String "-+0")],
[res_b9 -> (None)],
[b9 -> (String "--0")],
[res_b8 -> (None)],
[b8 -> (String "-")],
[res_b7 -> (None)],
[b7 -> (String "-00001Hello")],
[res_b6 -> (None)],
[b6 -> (String "-000000Hello")],
[res_b5 -> (None)],
[b5 -> (String "-0Hello")],
[res_b4 -> (None)],
[b4 -> (String "-Hello")],
[res_b3 -> (Some (Int32 0))],
[b3 -> (String "-00000")],
[res_b2 -> (Some (Int32 -123))],
[b2 -> (String "-00000123")],
[res_b1 -> (Some (Int32 -123))],
[b1 -> (String "-123")],
[res_a10 -> (None)],
[a10 -> (String "+-0")],
[res_a9 -> (None)],
[a9 -> (String "++0")],
[res_a8 -> (None)],
[a8 -> (String "+")],
[res_a7 -> (None)],
[a7 -> (String "+00001Hello")],
[res_a6 -> (None)],
[a6 -> (String "+000000Hello")],
[res_a5 -> (None)],
[a5 -> (String "+0Hello")],
[res_a4 -> (None)],
[a4 -> (String "+Hello")],
[res_a3 -> (Some (Int32 0))],
[a3 -> (String "+00000")],
[res_a2 -> (Some (Int32 123))],
[a2 -> (String "+00000123")],
[res_a1 -> (Some (Int32 123))],
[a1 -> (String "+123")] }
Gas remaining: 4001019
106 changes: 106 additions & 0 deletions tests/eval/good/int_lits.scilexp
@@ -0,0 +1,106 @@
(* Leading + *)
let a1 = "+123" in
let res_a1 = builtin to_int32 a1 in

let a2 = "+00000123" in
let res_a2 = builtin to_int32 a2 in

let a3 = "+00000" in
let res_a3 = builtin to_int32 a3 in

let a4 = "+Hello" in
let res_a4 = builtin to_int32 a4 in

let a5 = "+0Hello" in
let res_a5 = builtin to_int32 a5 in

let a6 = "+000000Hello" in
let res_a6 = builtin to_int32 a6 in

let a7 = "+00001Hello" in
let res_a7 = builtin to_int32 a7 in

let a8 = "+" in
let res_a8 = builtin to_int32 a8 in

let a9 = "++0" in
let res_a9 = builtin to_int32 a9 in

let a10 = "+-0" in
let res_a10 = builtin to_int32 a10 in

(* let an1 = Int32 +12 in *)
(* let an2 = Int32 +0012 in *)
(* let an3 = Int32 +0 in *)
(* let an4 = Int32 +0000 in *)

(* Leading - *)
let b1 = "-123" in
let res_b1 = builtin to_int32 b1 in

let b2 = "-00000123" in
let res_b2 = builtin to_int32 b2 in

let b3 = "-00000" in
let res_b3 = builtin to_int32 b3 in

let b4 = "-Hello" in
let res_b4 = builtin to_int32 b4 in

let b5 = "-0Hello" in
let res_b5 = builtin to_int32 b5 in

let b6 = "-000000Hello" in
let res_b6 = builtin to_int32 b6 in

let b7 = "-00001Hello" in
let res_b7 = builtin to_int32 b7 in

let b8 = "-" in
let res_b8 = builtin to_int32 b8 in

let b9 = "--0" in
let res_b9 = builtin to_int32 b9 in

let b10 = "-+0" in
let res_b10 = builtin to_int32 b10 in

let bn1 = Int32 -12 in
let bn2 = Int32 -0012 in
let bn3 = Int32 -0 in
let bn3 = Int32 -0000 in

(* Neither leading + nor leading - *)
let c1 = "123" in
let res_c1 = builtin to_int32 c1 in

let c2 = "00000123" in
let res_c2 = builtin to_int32 c2 in

let c3 = "00000" in
let res_c3 = builtin to_int32 c3 in

let c4 = "Hello" in
let res_c4 = builtin to_int32 c4 in

let c5 = "0Hello" in
let res_c5 = builtin to_int32 c5 in

let c6 = "000000Hello" in
let res_c6 = builtin to_int32 c6 in

let c7 = "00001Hello" in
let res_c7 = builtin to_int32 c7 in

let c8 = "" in
let res_c8 = builtin to_int32 c8 in

let c9 = "0" in
let res_c9 = builtin to_int32 c9 in

let cn1 = Int32 12 in
let cn2 = Int32 0012 in
let cn3 = Int32 0 in
let cn3 = Int32 0000 in

True

0 comments on commit 29ea7b2

Please sign in to comment.