aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Lång <[email protected]>2015-12-02 14:30:56 +0100
committerMagnus Lång <[email protected]>2015-12-02 14:38:31 +0100
commit33299ece737c635910e358d7e09dd8af6bce1a5d (patch)
tree6131cd6a0a9061d85aaf554c787d91514c2da024
parent21918b53a12107fdb1374387acd8b439515bd40d (diff)
downloadotp-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.c2
-rw-r--r--erts/emulator/test/bs_construct_SUITE.erl18
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.