1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19
20-module(evil_SUITE).
21
22-export([all/0, suite/0,
23         heap_frag/1,
24         encode_decode_ext/1,
25         decode_integer_ext/1,
26         decode_small_big_ext/1,
27         decode_large_big_ext/1,
28         decode_small_big_ext_neg/1,
29         decode_large_big_ext_neg/1,
30         decode_too_small/1,
31         decode_pos_neg_zero/1]).
32
33-include_lib("common_test/include/ct.hrl").
34
35suite() ->
36    [{ct_hooks,[ts_install_cth]},
37     {timetrap, {minutes, 1}}].
38
39all() ->
40    [heap_frag, encode_decode_ext, decode_integer_ext,
41     decode_small_big_ext, decode_large_big_ext,
42     decode_small_big_ext_neg, decode_large_big_ext_neg,
43     decode_too_small, decode_pos_neg_zero].
44
45heap_frag(Config) when is_list(Config) ->
46    N = 512,
47    Self = self(),
48    Pid = spawn_link(fun() -> appender(Self, N) end),
49    receive
50        {Pid,Res} ->
51            Res = my_appender(N);
52        Garbage ->
53            io:format("Garbage: ~p\n", [Garbage]),
54            ct:fail(got_garbage)
55    end.
56
57
58%% ######################################################################## %%
59
60%% "Interesting" integers taken from erl_interface ei_decode_SUITE.erl
61%% These test cases are not "evil" but the next test case is....
62
63encode_decode_ext(Config) when is_list(Config) ->
64    enc_dec( 2,   0),               % SMALL_INTEGER_EXT smallest
65    enc_dec( 2, 255),           	  % SMALL_INTEGER_EXT largest
66    enc_dec( 5, 256),           	  % INTEGER_EXT smallest pos (*)
67    enc_dec( 5,  -1),            	  % INTEGER_EXT largest  neg
68
69    enc_dec( 5, 16#07ffffff),  	  % INTEGER_EXT largest (28 bits)
70    enc_dec( 5,-16#08000000),  	  % INTEGER_EXT smallest
71    enc_dec( 7, 16#08000000),  	  % SMALL_BIG_EXT smallest pos(*)
72    enc_dec( 7,-16#08000001),  	  % SMALL_BIG_EXT largest neg (*)
73
74    enc_dec( 7, 16#7fffffff),  	  % SMALL_BIG_EXT largest  i32
75    enc_dec( 7,-16#80000000),  	  % SMALL_BIG_EXT smallest i32
76
77    enc_dec( 7, 16#80000000),  	  % SMALL_BIG_EXT u32
78    enc_dec( 7, 16#ffffffff),  	  % SMALL_BIG_EXT largest u32
79
80    enc_dec( 9, 16#7fffffffffff),     % largest  i48
81    enc_dec( 9,-16#800000000000),     % smallest i48
82    enc_dec( 9, 16#ffffffffffff),     % largest  u48
83    enc_dec(11, 16#7fffffffffffffff), % largest  i64
84    enc_dec(11,-16#8000000000000000), % smallest i64
85    enc_dec(11, 16#ffffffffffffffff), % largest  u64
86    ok.
87
88
89%% ######################################################################## %%
90
91%% "Interesting" integers taken from erl_interface ei_decode_SUITE.erl
92%% These test the decoding "unusual", i.e. integers packed according
93%% to "erts/emulator/internal_doc/erl_ext_dist.txt" but not the way
94%% the emulator or erl_interface encode them.
95%%
96%% NOTE!!!! The comments below after a decode line is how it currently
97%% is encoded in the external format by the emulator and
98%% erl_interface, i.e. not how it is encoded in the test case below.
99
100decode_integer_ext(Config) when is_list(Config) ->
101    decode(  0, <<131,98,  0:32>>),	% SMALL_INTEGER_EXT
102    decode( 42, <<131,98, 42:32>>),	% SMALL_INTEGER_EXT
103    decode(255, <<131,98,255:32>>),	% SMALL_INTEGER_EXT
104    decode( 16#08000000, <<131,98, 16#08000000:32>>), % SMALL_BIG_EXT
105    decode(-16#08000001, <<131,98,-16#08000001:32>>), % SMALL_BIG_EXT
106    decode( 16#7fffffff, <<131,98, 16#7fffffff:32>>), % SMALL_BIG_EXT
107    decode(-16#80000000, <<131,98,-16#80000000:32>>), % SMALL_BIG_EXT
108    ok.
109
110decode_small_big_ext(Config) when is_list(Config) ->
111    decode(256,<<131,110,2,0,0,1>>),	% INTEGER_EXT
112    decode(16#07ffffff,<<131,110,4,0,255,255,255,7>>), % INTEGER_EXT
113    decode(16#7fffffff,<<131,110,4,0,255,255,255,127>>), % SMALL_BIG_EXT
114
115    decode(42,<<131,110,1,0,42>>),	% SMALL_INTEGER_EXT
116    decode(42,<<131,110,2,0,42,0>>),	% Redundant zeros from now on
117    decode(42,<<131,110,3,0,42,0,0>>),
118    decode(42,<<131,110,4,0,42,0,0,0>>),
119    decode(42,<<131,110,5,0,42,0,0,0,0>>),
120    decode(42,<<131,110,6,0,42,0,0,0,0,0>>),
121    decode(42,<<131,110,7,0,42,0,0,0,0,0,0>>),
122    decode(42,<<131,110,8,0,42,0,0,0,0,0,0,0>>),
123    ok.
124
125decode_large_big_ext(Config) when is_list(Config) ->
126    decode(256,<<131,111,2:32,0,0,1>>), % INTEGER_EXT
127    decode(16#07ffffff,<<131,111,4:32,0,255,255,255,7>>), % INTEG_EXT
128    decode(16#7fffffff,<<131,111,4:32,0,255,255,255,127>>), % SMA_BIG
129    decode(16#ffffffff,<<131,111,4:32,0,255,255,255,255>>), % SMA_BIG
130
131    N = largest_small_big(),
132    decode(N,<<131,111,255:32,0,N:2040/little>>), % SMALL_BIG_EXT
133
134    decode(42,<<131,111,1:32,0,42>>),
135    decode(42,<<131,111,2:32,0,42,0>>), % Redundant zeros from now on
136    decode(42,<<131,111,3:32,0,42,0,0>>),
137    decode(42,<<131,111,4:32,0,42,0,0,0>>),
138    decode(42,<<131,111,5:32,0,42,0,0,0,0>>),
139    decode(42,<<131,111,6:32,0,42,0,0,0,0,0>>),
140    decode(42,<<131,111,7:32,0,42,0,0,0,0,0,0>>),
141    decode(42,<<131,111,8:32,0,42,0,0,0,0,0,0,0>>),
142    ok.
143
144decode_small_big_ext_neg(Config) when is_list(Config) ->
145    decode(-1,<<131,110,1,1,1>>),		% INTEGER_EXT
146    decode(-16#08000000,<<131,110,4,1,0,0,0,8>>), % INTEGER_EXT
147    decode(-16#80000000,<<131,110,4,1,0,0,0,128>>), % SMALL_BIG_EXT
148    decode(-16#ffffffff,<<131,110,4,1,255,255,255,255>>), % SMALL_BIG_EXT
149
150    N = largest_small_big(),
151    decode(-N,<<131,111,255:32,1,N:2040/little>>), % SMALL_BIG_EXT
152
153    decode(-42,<<131,110,1,1,42>>),
154    decode(-42,<<131,110,2,1,42,0>>),	% Redundant zeros from now on
155    decode(-42,<<131,110,3,1,42,0,0>>),
156    decode(-42,<<131,110,4,1,42,0,0,0>>),
157    decode(-42,<<131,110,5,1,42,0,0,0,0>>),
158    decode(-42,<<131,110,6,1,42,0,0,0,0,0>>),
159    decode(-42,<<131,110,7,1,42,0,0,0,0,0,0>>),
160    decode(-42,<<131,110,8,1,42,0,0,0,0,0,0,0>>),
161    ok.
162
163decode_large_big_ext_neg(Config) when is_list(Config) ->
164    decode(-1,<<131,111,1:32,1,1>>),	% INTEGER_EXT
165    decode(-16#08000000,<<131,111,4:32,1,0,0,0,8>>), % INTEGER_EXT
166    decode(-16#80000000,<<131,111,4:32,1,0,0,0,128>>), % SMALL_BIG_EXT
167
168    decode(-42,<<131,111,1:32,1,42>>),
169    decode(-42,<<131,111,2:32,1,42,0>>), % Redundant zeros from now on
170    decode(-42,<<131,111,3:32,1,42,0,0>>),
171    decode(-42,<<131,111,4:32,1,42,0,0,0>>),
172    decode(-42,<<131,111,5:32,1,42,0,0,0,0>>),
173    decode(-42,<<131,111,6:32,1,42,0,0,0,0,0>>),
174    decode(-42,<<131,111,7:32,1,42,0,0,0,0,0,0>>),
175    decode(-42,<<131,111,8:32,1,42,0,0,0,0,0,0,0>>),
176    ok.
177
178decode_pos_neg_zero(Config) when is_list(Config) ->
179    decode( 0, <<131,110,0,0>>),		% SMALL_BIG_EXT (positive zero)
180    decode( 0, <<131,110,1,0,0>>),	% SMALL_BIG_EXT (positive zero)
181    decode( 0, <<131,110,0,1>>),		% SMALL_BIG_EXT (negative zero)
182    decode( 0, <<131,110,1,1,0>>),	% SMALL_BIG_EXT (negative zero)
183
184    decode( 0, <<131,111,0:32,0>>),	% SMALL_BIG_EXT (positive zero)
185    decode( 0, <<131,111,1:32,0,0>>),	% SMALL_BIG_EXT (positive zero)
186    decode( 0, <<131,111,0:32,1>>),	% SMALL_BIG_EXT (negative zero)
187    decode( 0, <<131,111,1:32,1,0>>),	% SMALL_BIG_EXT (negative zero)
188
189    N = largest_small_big(),
190    decode( N,<<131,110,255,0,N:2040/little>>), % largest SMALL_BIG_EXT
191    decode(-N,<<131,110,255,1,N:2040/little>>), % largest SMALL_BIG_EXT
192
193    ok.
194
195%% Test to decode uncompleted encodings for all in "erl_ext_dist.txt"
196
197decode_too_small(Config) when is_list(Config) ->
198    decode_badarg(<<131, 97>>),
199    decode_badarg(<<131, 98>>),
200    decode_badarg(<<131, 98, 0>>),
201    decode_badarg(<<131, 98, 0, 0>>),
202    decode_badarg(<<131, 98, 0, 0, 0>>),
203    decode_badarg(<<131, 99>>),
204    decode_badarg(<<131, 99, 0>>),
205    decode_badarg(<<131, 99, 0:240>>),
206
207    decode_badarg(<<131,100>>),
208    decode_badarg(<<131,100, 1:16/big>>),
209    decode_badarg(<<131,100, 2:16/big>>),
210    decode_badarg(<<131,100, 2:16/big, "A">>),
211
212    % FIXME node name "A" seem ok, should it be?
213    %    decode_badarg(<<131,101,100,1:16/big,"A",42:32/big,0>>),
214
215    decode_badarg(<<131,101>>),
216    decode_badarg(<<131,101,106>>),
217    decode_badarg(<<131,101,255>>),
218    decode_badarg(<<131,101,106,42:8/big>>),
219    decode_badarg(<<131,101,106,42:16/big>>),
220    decode_badarg(<<131,101,255,42:24/big>>),
221    decode_badarg(<<131,101,255,42:32/big,0>>),
222    decode_badarg(<<131,101,100,1:16/big,"A">>),
223    decode_badarg(<<131,101,100,1:16/big,"A",42:32/big>>),
224
225    decode_badarg(<<131,102>>),
226    decode_badarg(<<131,102,106,42:32/big,0>>),
227    decode_badarg(<<131,102,255,42:32/big,0>>),
228    decode_badarg(<<131,102,100,1:16/big,"A">>),
229    decode_badarg(<<131,102,100,1:16/big,"A",42:32/big>>),
230
231    decode_badarg(<<131,103>>),
232    decode_badarg(<<131,103,106,42:32/big,0>>),
233    decode_badarg(<<131,103,255,42:32/big,0>>),
234    decode_badarg(<<131,103,100,1:16/big,"A">>),
235    decode_badarg(<<131,103,100,1:16/big,"A",42:32/big>>),
236    decode_badarg(<<131,103,100,1:16/big,"A",4:32/big,2:32/big>>),
237
238    decode_badarg(<<131,104>>),
239    decode_badarg(<<131,104, 1>>),
240    decode_badarg(<<131,104, 2, 106>>),
241    decode_badarg(<<131,105, 1:32/big>>),
242    decode_badarg(<<131,105, 2:32/big, 106>>),
243
244    decode_badarg(<<131,107>>),
245    decode_badarg(<<131,107, 1:16/big>>),
246    decode_badarg(<<131,107, 2:16/big>>),
247    decode_badarg(<<131,107, 2:16/big, "A">>),
248
249    decode_badarg(<<131,108>>),
250    decode_badarg(<<131,108, 1:32/big>>),
251    decode_badarg(<<131,108, 2:32/big>>),
252    decode_badarg(<<131,108, 2:32/big, 106>>), % FIXME don't use NIL
253
254    decode_badarg(<<131,109>>),
255    decode_badarg(<<131,109, 1:32/big>>),
256    decode_badarg(<<131,109, 2:32/big>>),
257    decode_badarg(<<131,109, 2:32/big, 42>>),
258
259    N = largest_small_big(),
260
261    decode_badarg(<<131,110>>),
262    decode_badarg(<<131,110,1>>),
263    decode_badarg(<<131,110,1,0>>),
264    decode_badarg(<<131,110,1,1>>),
265    decode_badarg(<<131,110,2,0,42>>),
266    decode_badarg(<<131,110,2,1,42>>),
267    decode_badarg(<<131,110,255,0,N:2032/little>>),
268    decode_badarg(<<131,110,255,1,N:2032/little>>),
269
270    decode_badarg(<<131,111>>),
271    decode_badarg(<<131,111,  1:32/big>>),
272    decode_badarg(<<131,111,  1:32/big,0>>),
273    decode_badarg(<<131,111,  1:32/big,1>>),
274    decode_badarg(<<131,111,  2:32/big,0,42>>),
275    decode_badarg(<<131,111,  2:32/big,1,42>>),
276    decode_badarg(<<131,111,256:32/big,0,N:2032/little>>),
277    decode_badarg(<<131,111,256:32/big,1,N:2032/little>>),
278    decode_badarg(<<131,111,256:32/big,0,N:2040/little>>),
279    decode_badarg(<<131,111,256:32/big,1,N:2040/little>>),
280    decode_badarg(<<131,111,257:32/big,0,N:2048/little>>),
281    decode_badarg(<<131,111,257:32/big,1,N:2048/little>>),
282
283    % Emulator dies if trying to create large bignum....
284    %    decode_badarg(<<131,111,16#ffffffff:32/big,0>>),
285    %    decode_badarg(<<131,111,16#ffffffff:32/big,1>>),
286
287    decode_badarg(<<131, 78>>),
288    decode_badarg(<<131, 78, 42>>),
289    decode_badarg(<<131, 78, 42, 1>>),
290    decode_badarg(<<131, 78, 42, 1:16/big>>),
291    decode_badarg(<<131, 78, 42, 2:16/big>>),
292    decode_badarg(<<131, 78, 42, 2:16/big, "A">>),
293
294    decode_badarg(<<131, 67>>),
295
296    decode_badarg(<<131,114>>),
297    decode_badarg(<<131,114,0>>),
298    decode_badarg(<<131,114,1:16/big>>),
299    decode_badarg(<<131,114,1:16/big,100>>),
300    decode_badarg(<<131,114,1:16/big,100,1:16/big>>),
301    decode_badarg(<<131,114,1:16/big,100,1:16/big,"A">>),
302    decode_badarg(<<131,114,1:16/big,100,1:16/big,"A",0>>),
303    decode_badarg(<<131,114,1:16/big,100,1:16/big,"A",0,42:8>>),
304    decode_badarg(<<131,114,1:16/big,100,1:16/big,"A",0,42:16>>),
305    decode_badarg(<<131,114,1:16/big,100,1:16/big,"A",0,42:24>>),
306
307    decode_badarg(<<131,117>>),		% FIXME needs more tests
308
309    ok.
310
311%% ######################################################################## %%
312
313decode_badarg(Bin) ->
314    io:format("Trying ~w\n",[Bin]),
315    {'EXIT',{badarg,_}} = (catch binary_to_term(Bin)).
316
317enc_dec(_Size, Term) ->
318    Bin = term_to_binary(Term),
319    Term = binary_to_term(Bin),
320    ok.
321
322decode(Term, Binary) ->
323    io:format("Encoding ~w to ~w ... ",[Binary,Term]),
324    NewTerm = binary_to_term(Binary),
325    io:format("got ~w\n",[NewTerm]),
326    Term = NewTerm.
327
328largest_small_big() ->
329    List  = lists:duplicate(255,255),
330    Limbs = list_to_binary(List),
331    binary_to_term(<<131,110,255,0,Limbs/binary>>).
332
333%% ######################################################################## %%
334
335appender(Parent, N) ->
336    seed(),
337    Res = appender_1(N, {}),
338    Parent ! {self(),Res}.
339
340appender_1(0, T) -> T;
341appender_1(N, T0) ->
342    U = rnd_term(),
343    T = erlang:append_element(T0, U),
344    appender_1(N-1, T).
345
346my_appender(N) ->
347    seed(),
348    my_appender_1(N, []).
349
350my_appender_1(0, T) ->
351    list_to_tuple(lists:reverse(T));
352my_appender_1(N, T0) ->
353    U = rnd_term(),
354    T = [U|T0],
355    my_appender_1(N-1, T).
356
357seed() ->
358    rand:seed(exsplus, {3172,9815,20129}).
359
360rnd_term() ->
361    U0 = rand:uniform(),
362    B = <<U0/float>>,
363    {U0,U0 * 2.5 + 3.14,[U0*2.3,B]}.
364