1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2001-2016. 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%%
21-module(testConstraints).
22
23-export([int_constraints/1,refed_NNL_name/1]).
24
25
26-include_lib("common_test/include/ct.hrl").
27
28int_constraints(Rules) ->
29    case Rules of
30        jer ->
31            {error,_} = 'Constraints':decode('SingleValue', <<"0">>),
32            {error,_} = 'Constraints':decode('SingleValue2', <<"21">>);
33        _ ->
34            ok
35    end,
36
37    %%==========================================================
38    %% SingleValue ::=  INTEGER (1)
39    %%==========================================================
40
41    range_error(Rules, 'SingleValue', 0),
42    roundtrip('SingleValue', 1),
43    range_error(Rules, 'SingleValue', 2),
44    range_error(Rules, 'SingleValue', 1000),
45
46    %%==========================================================
47    %% SingleValue2 ::=  INTEGER (1..20)
48    %%==========================================================
49
50    range_error(Rules, 'SingleValue2', 0),
51    roundtrip('SingleValue2', 1),
52    roundtrip('SingleValue2', 20),
53    range_error(Rules, 'SingleValue2', 21),
54    range_error(Rules, 'SingleValue2', 1000),
55
56    %%==========================================================
57    %% SingleValue3 ::=  INTEGER (Predefined | 5 | 10)
58    %% Testcase for OTP-10139. A single value subtyping of an integer type
59    %% where one value is predefined.
60    %%==========================================================
61
62    roundtrip('SingleValue3', 1),
63    roundtrip('SingleValue3', 5),
64    roundtrip('SingleValue3', 10),
65
66    %%==========================================================
67    %% Range2to19 ::=  INTEGER (1<..<20)
68    %%==========================================================
69
70    range_error(Rules, 'Range2to19', 1),
71    roundtrip('Range2to19', 2),
72    roundtrip('Range2to19', 19),
73    range_error(Rules, 'Range2to19', 20),
74
75    %%==========================================================
76    %% Tests for Range above 16^4 up to maximum supported by asn1 assuming the
77    %% octet length field is encoded on max 8 bits
78    %%==========================================================
79    LastNumWithoutLengthEncoding = 65536,
80    roundtrip('Range256to65536', LastNumWithoutLengthEncoding),
81    roundtrip('Range256to65536Ext', LastNumWithoutLengthEncoding),
82    roundtrip('Range256to65536Ext', 42),
83
84    FirstNumWithLengthEncoding = 65537,
85    roundtrip('LargeConstraints', 'RangeMax', FirstNumWithLengthEncoding),
86
87    FirstNumOver16_6 = 16777217,
88    roundtrip('LargeConstraints', 'RangeMax', FirstNumOver16_6),
89
90    FirstNumOver16_8 = 4294967297,
91    roundtrip('LargeConstraints', 'RangeMax', FirstNumOver16_8),
92
93    FirstNumOver16_10 = 1099511627776,
94    roundtrip('LargeConstraints', 'RangeMax', FirstNumOver16_10),
95
96    FirstNumOver16_10 = 1099511627776,
97    roundtrip('LargeConstraints', 'RangeMax', FirstNumOver16_10),
98
99    HalfMax = 1 bsl (128*8),
100    roundtrip('LargeConstraints', 'RangeMax', HalfMax),
101
102    Max = 1 bsl (255*8),
103    roundtrip('LargeConstraints', 'RangeMax', Max),
104
105    %% Random number within longlong range
106    LongLong = 12672809400538808320,
107    roundtrip('LongLong', LongLong),
108    roundtrip('LongLongExt', LongLong),
109    roundtrip('LongLongExt', -10000),
110
111    %%==========================================================
112    %%  Constraint Combinations (Duboisson p. 285)
113    %%  I ::= INTEGER (0|15..269)
114    %%==========================================================
115
116    range_error(Rules, 'I', -1),
117    roundtrip('I', 0),
118    roundtrip('I', 15),
119    roundtrip('I', 20),
120    roundtrip('I', 269),
121    range_error(Rules, 'I', 270),
122
123    %%==========================================================
124    %%  Constraint Combinations (Duboisson p. 285)
125    %%  X1 ::= INTEGER (1..4|8|10|20)
126    %%==========================================================
127
128    range_error(Rules, 'X1', 0),
129    roundtrip('X1', 1),
130    roundtrip('X1', 4),
131    roundtrip('X1', 8),
132    roundtrip('X1', 10),
133    roundtrip('X1', 20),
134    range_error(Rules, 'X1', 21),
135
136    %%==========================================================
137    %%  Union of single values
138    %%  Sv1 ::= INTEGER (2|3|17)
139    %%  Sv2 ::= INTEGER (2|3|17, ...)
140    %%  Sv3 ::= INTEGER {a(2),b(3),z(17)} (2|3|17, ...)
141    %%==========================================================
142
143    range_error(Rules, 'Sv1', 1),
144    range_error(Rules, 'Sv1', 18),
145    roundtrip('Sv1', 2),
146    roundtrip('Sv1', 3),
147    roundtrip('Sv1', 7),
148
149    %% Encoded as root
150    v_roundtrip(Rules, 'Sv2', 2),
151    v_roundtrip(Rules, 'Sv2', 3),
152    v_roundtrip(Rules, 'Sv2', 17),
153
154    %% Encoded as extension
155    v_roundtrip(Rules, 'Sv2', 1),
156    v_roundtrip(Rules, 'Sv2', 4),
157    v_roundtrip(Rules, 'Sv2', 18),
158
159    %% Encoded as root
160    v_roundtrip(Rules, 'Sv3', a),
161    v_roundtrip(Rules, 'Sv3', b),
162    v_roundtrip(Rules, 'Sv3', z),
163    v_roundtrip(Rules, 'Sv3', 2, a),
164    v_roundtrip(Rules, 'Sv3', 3, b),
165    v_roundtrip(Rules, 'Sv3', 17, z),
166
167    %% Encoded as extension
168    v_roundtrip(Rules, 'Sv3', 1),
169    v_roundtrip(Rules, 'Sv3', 4),
170    v_roundtrip(Rules, 'Sv3', 18),
171
172    %%==========================================================
173    %%  SemiConstrained
174    %%==========================================================
175
176    roundtrip('SemiConstrained', 100),
177    v_roundtrip(Rules, 'SemiConstrained', 100+128),
178    roundtrip('SemiConstrained', 397249742397243),
179    roundtrip('SemiConstrained', 100 + 1 bsl 128*8),
180    roundtrip('SemiConstrained', 100 + 1 bsl 256*8),
181
182    roundtrip('NegSemiConstrained', -128),
183    v_roundtrip(Rules, 'NegSemiConstrained', 0),
184    roundtrip('NegSemiConstrained', -1),
185    roundtrip('NegSemiConstrained', 500),
186
187    roundtrip('SemiConstrainedExt', -65536),
188    roundtrip('SemiConstrainedExt', 0),
189    roundtrip('SemiConstrainedExt', 42),
190    v_roundtrip(Rules, 'SemiConstrainedExt', 42+128),
191    roundtrip('SemiConstrainedExt', 100),
192    roundtrip('SemiConstrainedExt', 47777789),
193    roundtrip('SemiConstrainedExt', 42 + 1 bsl 128*8),
194    roundtrip('SemiConstrainedExt', 42 + 1 bsl 256*8),
195
196    roundtrip('NegSemiConstrainedExt', -1023),
197    roundtrip('NegSemiConstrainedExt', -128),
198    roundtrip('NegSemiConstrainedExt', -1),
199    v_roundtrip(Rules, 'NegSemiConstrainedExt', 0),
200    roundtrip('NegSemiConstrainedExt', 500),
201
202    %%==========================================================
203    %%  SIZE Constraint (Duboisson p. 268)
204    %%  T ::=  IA5String (SIZE (1|2, ..., SIZE (1|2|3)))
205    %%  T2 ::= IA5String (SIZE (1|2, ..., 3))
206    %%==========================================================
207
208    roundtrip('T', "IA"),
209    roundtrip('T', "IAB"),
210    roundtrip('T', "IABC"),
211    roundtrip('T2', "IA"),
212    roundtrip('T2', "IAB"),
213    roundtrip('T2', "IABC"),
214
215    %%==========================================================
216    %%  More SIZE Constraints
217    %%==========================================================
218
219    roundtrip('FixedSize', <<"0123456789">>),
220    roundtrip('FixedSize2', <<"0123456789">>),
221    roundtrip('FixedSize2', <<"0123456789abcdefghij">>),
222
223    range_error(Rules, 'FixedSize', "short"),
224    range_error(Rules, 'FixedSize2', "short"),
225
226    [roundtrip('VariableSize', list_to_binary(lists:seq($A, $A+L-1))) ||
227	L <- lists:seq(1, 10)],
228
229    roundtrip_enc('ShorterExt', "a", shorter_ext(Rules, "a")),
230    roundtrip('ShorterExt', "abcde"),
231    roundtrip('ShorterExt', "abcdef"),
232
233    %%==========================================================
234    %%  Unions of INTEGER constraints
235    %%==========================================================
236    seq_roundtrip(Rules, 'SeqOverlapping', 'SeqNonOverlapping', 7580),
237    seq_roundtrip(Rules, 'SeqOverlapping', 'SeqNonOverlapping', 9600),
238    seq_roundtrip(Rules, 'SeqOverlapping', 'SeqNonOverlapping', 18050),
239    seq_roundtrip(Rules, 'SeqOverlapping', 'SeqNonOverlapping', 19000),
240    seq_roundtrip(Rules, 'SeqOverlapping', 'SeqNonOverlapping', 26900),
241
242    %%==========================================================
243    %%  Constraints from object fields.
244    %%==========================================================
245    range_error(Rules, 'IntObjectConstr', 1),
246    roundtrip('IntObjectConstr', 2),
247    roundtrip('IntObjectConstr', 3),
248    roundtrip('IntObjectConstr', 4),
249    range_error(Rules, 'IntObjectConstr', 5),
250
251
252    %%==========================================================
253    %% INTEGER constraints defined using named INTEGERs.
254    %%==========================================================
255    42 = 'Constraints':'constrainedNamedInt-1'(),
256    100 = 'Constraints':'constrainedNamedInt-2'(),
257    range_error(Rules, 'ConstrainedNamedInt', 41),
258    roundtrip('ConstrainedNamedInt', v1),
259    range_error(Rules, 'ConstrainedNamedInt', 43),
260
261    range_error(Rules, 'SeqWithNamedInt', {'SeqWithNamedInt',-100}),
262    roundtrip('SeqWithNamedInt', {'SeqWithNamedInt',v2}),
263
264    ok.
265
266%% PER: Ensure that if the lower bound is Lb, Lb+16#80 is encoded
267%% in two bytes as 16#0180. (Not in three bytes as 16#010080.)
268v(ber, 'SemiConstrained', 100+128) -> "020200E4";
269v(per, 'SemiConstrained', 100+128) -> "0180";
270v(uper, 'SemiConstrained', 100+128) -> "0180";
271v(ber, 'NegSemiConstrained', 0) -> "020100";
272v(per, 'NegSemiConstrained', 0) -> "0180";
273v(uper, 'NegSemiConstrained', 0) -> "0180";
274v(ber, 'SemiConstrainedExt', 42+128) -> "020200AA";
275v(per, 'SemiConstrainedExt', 42+128) -> "000180";
276v(uper, 'SemiConstrainedExt', 42+128) -> "00C000";
277v(ber, 'NegSemiConstrainedExt', 0) -> "020100";
278v(per, 'NegSemiConstrainedExt', 0) -> "000180";
279v(uper, 'NegSemiConstrainedExt', 0) -> "00C000";
280v(ber, 'Sv2', 1) -> "020101";
281v(per, 'Sv2', 1) -> "800101";
282v(uper, 'Sv2', 1) -> "808080";
283v(ber, 'Sv2', 2) -> "020102";
284v(per, 'Sv2', 2) -> "00";
285v(uper, 'Sv2', 2) -> "00";
286v(ber, 'Sv2', 3) -> "020103";
287v(per, 'Sv2', 3) -> "08";
288v(uper, 'Sv2', 3) -> "08";
289v(ber, 'Sv2', 4) -> "020104";
290v(per, 'Sv2', 4) -> "800104";
291v(uper, 'Sv2', 4) -> "808200";
292v(ber, 'Sv2', 17) -> "020111";
293v(per, 'Sv2', 17) -> "78";
294v(uper, 'Sv2', 17) -> "78";
295v(ber, 'Sv2', 18) -> "020112";
296v(per, 'Sv2', 18) -> "800112";
297v(uper, 'Sv2', 18) -> "808900";
298v(Rule, 'Sv3', a) -> v(Rule, 'Sv2', 2);
299v(Rule, 'Sv3', b) -> v(Rule, 'Sv2', 3);
300v(Rule, 'Sv3', z) -> v(Rule, 'Sv2', 17);
301v(Rule, 'Sv3', Val) when is_integer(Val) -> v(Rule, 'Sv2', Val).
302
303shorter_ext(per, "a") -> <<16#80,16#01,16#61>>;
304shorter_ext(uper, "a") -> <<16#80,16#E1>>;
305shorter_ext(ber, _) -> none;
306shorter_ext(jer, _) -> none.
307
308refed_NNL_name(_Erule) ->
309    roundtrip('AnotherThing', fred),
310    {error,_Reason} = 'Constraints':encode('AnotherThing', fred3).
311
312v_roundtrip(jer,_,_) -> ok;
313v_roundtrip(Erule, Type, Value) ->
314    Encoded = asn1_test_lib:hex_to_bin(v(Erule, Type, Value)),
315    Encoded = roundtrip('Constraints', Type, Value).
316
317v_roundtrip(jer,_,_,_) -> ok;
318v_roundtrip(Erule, Type, Value, Expected) ->
319    Encoded = asn1_test_lib:hex_to_bin(v(Erule, Type, Value)),
320    Encoded = asn1_test_lib:roundtrip_enc('Constraints', Type, Value, Expected).
321
322roundtrip(Type, Value) ->
323    roundtrip('Constraints', Type, Value).
324
325roundtrip(Module, Type, Value) ->
326    asn1_test_lib:roundtrip_enc(Module, Type, Value).
327
328roundtrip_enc(Type, Value, Enc) ->
329    Encoded = asn1_test_lib:roundtrip_enc('Constraints', Type, Value),
330    case Enc of
331	none -> ok;
332	Encoded -> ok
333    end.
334
335range_error(ber, Type, Value) ->
336    %% BER: Values outside the effective range should be rejected
337    %% on decode.
338    {ok,Encoded} = 'Constraints':encode(Type, Value),
339    {error,{asn1,_}} = 'Constraints':decode(Type, Encoded),
340    ok;
341range_error(Per, Type, Value) when Per =:= per; Per =:= uper; Per =:= jer ->
342    %% (U)PER: Values outside the effective range should be rejected
343    %% on encode.
344    {error,_} = 'Constraints':encode(Type, Value),
345    ok.
346
347seq_roundtrip(Rules, Seq1, Seq2, Val) ->
348    Enc = roundtrip(Seq1, {Seq1,Val}),
349    case Rules of
350	ber ->
351	    roundtrip(Seq2, {Seq2,Val});
352	_ ->
353	    roundtrip_enc(Seq2, {Seq2,Val}, Enc)
354    end.
355