aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/test
diff options
context:
space:
mode:
authorMagnus Lång <[email protected]>2015-12-01 15:24:25 +0000
committerMagnus Lång <[email protected]>2015-12-02 15:58:15 +0100
commit34380bad4985bc827866129597e0bea940e076f4 (patch)
tree24374b86fc83e9e667df7697e76a5cf3ccc8b728 /lib/hipe/test
parent33299ece737c635910e358d7e09dd8af6bce1a5d (diff)
downloadotp-34380bad4985bc827866129597e0bea940e076f4.tar.gz
otp-34380bad4985bc827866129597e0bea940e076f4.tar.bz2
otp-34380bad4985bc827866129597e0bea940e076f4.zip
hipe: Fix signed compares of unsigned sizes
Also, some of the branches were testing sizes in bits against a constant ?MAX_BINSIZE, which was in bytes. The signed comparisons masked this mistake. These branches have been removed since all sizes in bits that fit in a machine word are valid binary sizes. Finally, a test that reproduces the issue was added to bs_construct, along with a test for one of the cases (bs_init<0>(...)) when the test against ?MAX_BINSIZE must be changed to unsigned rather than removed.
Diffstat (limited to 'lib/hipe/test')
-rw-r--r--lib/hipe/test/bs_SUITE_data/bs_construct.erl34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/hipe/test/bs_SUITE_data/bs_construct.erl b/lib/hipe/test/bs_SUITE_data/bs_construct.erl
index 7251cdce43..b9e7d93570 100644
--- a/lib/hipe/test/bs_SUITE_data/bs_construct.erl
+++ b/lib/hipe/test/bs_SUITE_data/bs_construct.erl
@@ -18,6 +18,7 @@ test() ->
ok = bad_append(),
ok = system_limit(),
ok = bad_floats(),
+ ok = huge_binaries(),
ok.
%%--------------------------------------------------------------------
@@ -269,3 +270,36 @@ bad_floats() ->
{'EXIT',{badarg,_}} = (catch <<3.14:(id((1 bsl 28) bor 32))/float>>),
{'EXIT',{system_limit,_}} = (catch <<3.14:(id(1 bsl BitsPerWord))/float>>),
ok.
+
+%%--------------------------------------------------------------------
+%% A bug in the implementation of binaries compared sizes in bits with sizes in
+%% bytes, causing <<0:(id((1 bsl 31)-1))>> to fail to construct with
+%% 'system_limit'.
+%% <<0:(id((1 bsl 32)-1))>> was succeeding because the comparison was
+%% (incorrectly) signed.
+
+huge_binaries() ->
+ AlmostIllegal = id(<<0:(id((1 bsl 32)-8))>>),
+ case erlang:system_info(wordsize) of
+ 4 -> huge_binaries_32(AlmostIllegal);
+ 8 -> ok
+ end,
+ garbage_collect(),
+ id(<<0:(id((1 bsl 31)-1))>>),
+ id(<<0:(id((1 bsl 30)-1))>>),
+ garbage_collect(),
+ ok.
+
+huge_binaries_32(AlmostIllegal) ->
+ %% Attempt construction of too large binary using bs_init/1 (which takes the
+ %% number of bytes as an argument, which should be compared to the maximum
+ %% size in bytes).
+ {'EXIT',{system_limit,_}} = (catch <<0:32,AlmostIllegal/binary>>),
+ %% Attempt construction of too large binary using bs_init/1 with a size in
+ %% bytes that has the msb set (and would be negative if it was signed).
+ {'EXIT',{system_limit,_}} =
+ (catch <<0:8, AlmostIllegal/binary, AlmostIllegal/binary,
+ AlmostIllegal/binary, AlmostIllegal/binary,
+ AlmostIllegal/binary, AlmostIllegal/binary,
+ AlmostIllegal/binary, AlmostIllegal/binary>>),
+ ok.