diff options
author | Magnus Lång <[email protected]> | 2015-12-02 14:30:56 +0100 |
---|---|---|
committer | Magnus Lång <[email protected]> | 2015-12-02 14:38:31 +0100 |
commit | 33299ece737c635910e358d7e09dd8af6bce1a5d (patch) | |
tree | 6131cd6a0a9061d85aaf554c787d91514c2da024 | |
parent | 21918b53a12107fdb1374387acd8b439515bd40d (diff) | |
download | otp-33299ece737c635910e358d7e09dd8af6bce1a5d.tar.gz otp-33299ece737c635910e358d7e09dd8af6bce1a5d.tar.bz2 otp-33299ece737c635910e358d7e09dd8af6bce1a5d.zip |
beam: Fix overflow bug in i_bs_add_jId
The test whether the result would fit in a smallnum could overflow into
a negative number that would fit a smallnum. A test that reproduces the
issue was added to bs_construct_SUITE.
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 2 | ||||
-rw-r--r-- | erts/emulator/test/bs_construct_SUITE.erl | 18 |
2 files changed, 17 insertions, 3 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 38def5d89f..73292885ce 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -4069,7 +4069,7 @@ do { \ tmp_arg1 += Arg1; store_bs_add_result: - if (MY_IS_SSMALL((Sint) tmp_arg1)) { + if (tmp_arg1 <= MAX_SMALL) { tmp_arg1 = make_small(tmp_arg1); } else { /* diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl index 1afd01e27b..f2bd6c233a 100644 --- a/erts/emulator/test/bs_construct_SUITE.erl +++ b/erts/emulator/test/bs_construct_SUITE.erl @@ -29,7 +29,7 @@ mem_leak/1, coerce_to_float/1, bjorn/1, huge_float_field/1, huge_binary/1, system_limit/1, badarg/1, copy_writable_binary/1, kostis/1, dynamic/1, bs_add/1, - otp_7422/1, zero_width/1, bad_append/1]). + otp_7422/1, zero_width/1, bad_append/1, bs_add_overflow/1]). -include_lib("test_server/include/test_server.hrl"). @@ -40,7 +40,7 @@ all() -> in_guard, mem_leak, coerce_to_float, bjorn, huge_float_field, huge_binary, system_limit, badarg, copy_writable_binary, kostis, dynamic, bs_add, otp_7422, zero_width, - bad_append]. + bad_append, bs_add_overflow]. groups() -> []. @@ -925,5 +925,19 @@ append_unit_8(Bin) -> append_unit_16(Bin) -> <<Bin/binary-unit:16,0:1>>. +%% Produce a large result of bs_add that would fit a smallnum if it was viewed +%% as signed. +bs_add_overflow(Config) -> + case erlang:system_info(wordsize) of + 8 -> + {skip, "64-bit architecture"}; + 4 -> + Large = <<0:((1 bsl 30)-1)>>, + {'EXIT',{system_limit,_}} = + (catch <<Large/bits, Large/bits, Large/bits, Large/bits, + Large/bits, Large/bits, Large/bits, Large/bits, + Large/bits>>), + ok + end. id(I) -> I. |