aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/test
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2014-11-19 12:41:23 +0100
committerBjörn Gustavsson <[email protected]>2015-01-12 11:40:28 +0100
commit65edabb2b428c74702d11194847676baf4025a85 (patch)
tree98e06b1c57393ea9ad994a6b5dc83b8f812d21c5 /lib/asn1/test
parent366e3adf2dd6e33e161909ba5575f9475edd523b (diff)
downloadotp-65edabb2b428c74702d11194847676baf4025a85.tar.gz
otp-65edabb2b428c74702d11194847676baf4025a85.tar.bz2
otp-65edabb2b428c74702d11194847676baf4025a85.zip
Rewrite constraint handling
The internal representation for constraints (and object sets) as produced by the parser was awkward, making further processing convoluted. Here follows some examples of the old representation for INTEGER constraints. The constraint 1..2 is represented as: {'ValueRange',{1,2}} If we extend the constraint like this: 1..2, ..., or like this: 1..2, ..., 3 the representation would be: {{'ValueRange',{1,2}},[]} and {{'ValueRange',{1,2}},{'SingleValue',3}} respectively. Note that the pattern {A,B} will match all these constraints. When combining constraints using set operators: 1..2 | 3..4 ^ 5..6 the representation will no longer be a tuple but a list: [{'ValueRange',{1..2}} union {'ValueRange',{3..4}} intersection {'ValueRange',{5..6}}] The parse has full knowledge of the operator precedence; unfortunately, the following pass (asn1ct_check) must also have the same knowledge in order to correctly evaluate the constraints. If we would change the order of the evaulation with round brackets: (1..2 | 3..4) ^ 5..6 there would be a nested listed in the representation: [[{'ValueRange',{1..2}} union {'ValueRange',{3..4}}] intersection {'ValueRange',{5..6}}] We will change the representation to make it more explicit. At the outer level, a constraint is always represented as {element_set,Root,Extension} Extension will be 'none' if there is no extension, and 'empty' if there is an empty extension. Root may also be 'empty' in an object set if there are no objects in the root. Thus the constraints: 1..2 1..2, ... 1..2, ..., 3 will be represented as: {element_set,{'ValueRange',{1,2}},none} {element_set,{'ValueRange',{1,2}},empty} {element_set,{'ValueRange',{1,2}},{'SingleValue',3}} We will change the set operators too. This constraint: 1..2 | 3..4 ^ 5..6 will be represented as: {element_set, {union, {'ValueRange',{1,2}}, {intersection, {'ValueRange',{3,4}}, {'ValueRange',{5,6}}}, none}} which is trivial to understand and evaluate. Similarly: (1..2 | 3..4) ^ 5..6 will be represented as: {element_set, {intersection, {union,{'ValueRange',{1,2}},{'ValueRange',{3,4}}}, {'ValueRange',{5,6}}}, none}
Diffstat (limited to 'lib/asn1/test')
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn160
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Constraints.py2
-rw-r--r--lib/asn1/test/error_SUITE.erl16
3 files changed, 68 insertions, 10 deletions
diff --git a/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1 b/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1
index 8b3d151502..648275dd66 100644
--- a/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/ConstraintEquivalence.asn1
@@ -11,6 +11,10 @@ BEGIN
SingleValueX8 ::= INTEGER (integer42)
SingleValueX9 ::= INTEGER (integer42..integer42)
SingleValueX10 ::= INTEGER ((integer42) INTERSECTION (40..49))
+ SingleValueX11 ::= INTEGER (40..49) (integer42)
+ SingleValueX12 ::= INTEGER ((MIN..0) ^ (1..10) | integer42)
+ SingleValueX13 ::= INTEGER ((11..20) ^ (1..10) | integer42)
+ SingleValueX14 ::= INTEGER ((MIN..42) ^ (1..100) ^ (42..50))
UnconstrainedX0 ::= INTEGER
UnconstrainedX1 ::= INTEGER (MIN..MAX)
@@ -19,6 +23,10 @@ BEGIN
UnconstrainedX4 ::= INTEGER ((MIN..MAX)|9|10)
UnconstrainedX5 ::= INTEGER ((MIN..MAX)|10..20)
UnconstrainedX6 ::= INTEGER ((MIN..MAX) UNION (10..20))
+ UnconstrainedX7 ::= INTEGER ((MIN..MAX) ^ ((MIN..MAX) UNION (10..20)))
+ UnconstrainedX8 ::= INTEGER ((-100..MAX) ^ (42..MAX) | (MIN..41))
+ UnconstrainedX9 ::= INTEGER (UnconstrainedX0)
+ UnconstrainedX10 ::= INTEGER (UnconstrainedX0)(MIN..MAX)
RangeX00 ::= INTEGER (5..10)
RangeX01 ::= INTEGER (4<..<11)
@@ -38,22 +46,66 @@ BEGIN
RangeX16 ::= INTEGER ((5|6) UNION (7) UNION (7<..<11))
RangeX20 ::= INTEGER (0..20) (5..10)
- RangeX21 ::= INTEGER (0..10) (5..20)
- RangeX22 ::= INTEGER (0..10) (5..20) (MIN..MAX)
- RangeX23 ::= INTEGER ((0..10) INTERSECTION (5..20) ^ (MIN..MAX))
- RangeX24 ::= INTEGER ((5|6|7|8|9|10) INTERSECTION (5..20) ^ (MIN..MAX))
+ RangeX21 ::= INTEGER ((0..10) ^ (5..20))
+ RangeX22 ::= INTEGER ((0..10) ^ (5..20) ^ (MIN..MAX))
+ RangeX23 ::= INTEGER (MIN..MAX) (-100..20) (5..10)
+ RangeX24 ::= INTEGER (MIN..MAX) (0..100) (5..20) (5..10)
+ RangeX25 ::= INTEGER ((0..10) INTERSECTION (5..20) ^ (MIN..MAX))
+ RangeX26 ::= INTEGER ((5|6|7|8|9|10) INTERSECTION (5..20) ^ (MIN..MAX))
+
+ RangeX30 ::= INTEGER (((5|6) | (5..20)) ^ (0..10))
+ RangeX31 ::= INTEGER (((((5|6) | (5..20)) ^ (0..10))) ^ (MIN..MAX))
+ RangeX32 ::= INTEGER ((5|7) | (5..10))
+
+ Semi00 ::= INTEGER (0..MAX)
+ Semi01 ::= INTEGER (0..MAX) (MIN..MAX)
+ Semi02 ::= INTEGER ((0..100) UNION (200..MAX) UNION (50..1024))
+
+ RangeExtX00 ::= INTEGER (5..10, ...)
+ RangeExtX01 ::= INTEGER (0..20) (5..10, ...)
+ RangeExtX02 ::= INTEGER (RangeX26) (5..10, ...)
+-- RangeExtX03 ::= RangeX26 (5..10, ...)
+
+ MinRangeX00 ::= INTEGER (MIN..10)
+ MinRangeX01 ::= INTEGER ((MIN..0) | (0..10))
+ MinRangeX02 ::= INTEGER (MIN..MAX) (MIN..100) (MIN..10)
+ MinRangeX03 ::= INTEGER (((MIN..-100)|(-60..-50)) | (MIN..10))
+
+ DisjointRangeX00 ::= INTEGER (0..5 UNION 95..99)
+ DisjointRangeX01 ::= INTEGER (0|1|2|3|4|5|95|96|97|98|99)
+ DisjointRangeX02 ::= INTEGER (0..100) (0..2 UNION 95..99 UNION 3|4|5)
+ DisjointRangeX03 ::= INTEGER (MIN..MAX) (0..2 UNION 95..99 UNION 3|4|5)
+
+ MinDisjointRangeX00 ::= INTEGER (MIN..-100 UNION 100..1000)
+ MinDisjointRangeX01 ::= INTEGER (MIN..-100 UNION 100..1000 UNION (MIN..-100))
+ MinDisjointRangeX02 ::= INTEGER (MIN..-50000 UNION 100..1000 UNION (MIN..-100))
+ MinDisjointRangeX03 ::= INTEGER (MIN..-100 UNION 100..1000 UNION (MIN..-1000000))
+ MinDisjointRangeX04 ::= INTEGER (MIN..-100 UNION 100..1000 UNION (MIN..-1000000))
+ MinDisjointRangeX05 ::= INTEGER (MIN..-100 ^ (MIN..-100) UNION 100..1000)
+ MinDisjointRangeX06 ::= INTEGER (MIN..-100 ^ (MIN..0) UNION 100..1000)
UnconstrainedStringX00 ::= IA5String
UnconstrainedStringX01 ::= IA5String (SIZE (0..MAX))
+ UnconstrainedStringX02 ::= IA5String (SIZE (0..42|43..MAX))
ConstrainedStringX00 ::= IA5String (SIZE (0..5))
ConstrainedStringX01 ::= IA5String (SIZE (0|1|2|3|4|5))
+ StringExtFromX00 ::= IA5String (FROM ("AB", ..., "CD"))(SIZE (1..10, ..., 15..20))
+ StringExtFromX01 ::= IA5String (FROM ("AB", ..., "CD"))(SIZE (1..10, ..., 15..20))
+ StringExtFromX02 ::= IA5String ((FROM ("AB", ..., "CD")) ^ ((SIZE (1..10, ..., 15..20))))
+ StringExtFromX03 ::= IA5String ((FROM ("AB", ..., "CD")) ^ (SIZE (1..10, ..., 15..20)))
+ StringExtFromX04 ::= IA5String (StringExtFromX00)
+
-- Note: None of the back-ends care about the exact values
-- outside of the root range.
ExtConstrainedStringX00 ::= IA5String (SIZE (1..2, ...))
ExtConstrainedStringX01 ::= IA5String (SIZE (1|2, ..., 3))
ExtConstrainedStringX02 ::= IA5String (SIZE (1|2, ..., 3|4|5))
+ ExtConstrainedStringX03 ::= IA5String (SIZE (1|2, ..., 1|2|3|4|5))
+ ExtConstrainedStringX04 ::= IA5String (SIZE (1|2), ..., SIZE (1|2|3|4|5))
+ ExtConstrainedStringX05 ::= IA5String (SIZE (1|2, ...), ...,
+ SIZE (1|2|3|4|5, ...))
integer4 INTEGER ::= 4
integer11 INTEGER ::= 11
diff --git a/lib/asn1/test/asn1_SUITE_data/Constraints.py b/lib/asn1/test/asn1_SUITE_data/Constraints.py
index 2df95da8a2..a40c513141 100644
--- a/lib/asn1/test/asn1_SUITE_data/Constraints.py
+++ b/lib/asn1/test/asn1_SUITE_data/Constraints.py
@@ -81,7 +81,7 @@ maxNrOfCellPortionsPerCell-1 INTEGER ::= 35
CellPortionID ::= INTEGER (0..maxNrOfCellPortionsPerCell-1,...)
-- OTP-6763
-T ::= IA5String (SIZE (1|2, ..., SIZE (1|2|3))) -- Dubuisson 268
+T ::= IA5String (SIZE (1|2), ..., SIZE (1|2|3)) -- Dubuisson 268
T2 ::= IA5String (SIZE (1|2, ..., 3)) -- equal with T
-- OTP-8046
diff --git a/lib/asn1/test/error_SUITE.erl b/lib/asn1/test/error_SUITE.erl
index bcb31cb3bb..d81eac7017 100644
--- a/lib/asn1/test/error_SUITE.erl
+++ b/lib/asn1/test/error_SUITE.erl
@@ -124,6 +124,7 @@ constraints(Config) ->
" II-1 ::= INTEGER (holder-1.&obj)\n"
" II-2 ::= INTEGER ('1234'H<..20)\n"
" II-3 ::= INTEGER (1..<\"abc\")\n"
+ " II-4 ::= INTEGER (10..1)\n"
" HOLDER ::= CLASS {\n"
" &obj HOLDER OPTIONAL\n"
@@ -136,7 +137,8 @@ constraints(Config) ->
[
{structured_error,{M,2},asn1ct_check,illegal_value},
{structured_error,{M,3},asn1ct_check,illegal_integer_value},
- {structured_error,{M,4},asn1ct_check,illegal_integer_value}
+ {structured_error,{M,4},asn1ct_check,illegal_integer_value},
+ {structured_error,{M,5},asn1ct_check,reversed_range}
]} = run(P, Config),
ok.
@@ -595,13 +597,14 @@ table_constraints(Config) ->
" }\n"
" Seq-2 ::= SEQUENCE {\n"
- " contentType INTEGER({Contents}),\n"
+ " contentType INTEGER,\n"
" content CONTENTS.&Type({Contents}{@contentType})\n"
" }\n"
+ " Int ::= INTEGER ({1})\n"
+
" Seq-3 ::= SEQUENCE {\n"
- " contentType INTEGER,\n"
- " content CONTENTS.&Type({Contents}{@contentType})\n"
+ " contentType CONTENTS.&id({1})\n"
" }\n"
"Contents CONTENTS ::= {\n"
@@ -619,7 +622,10 @@ table_constraints(Config) ->
{missing_ocft,contentType}},
{structured_error,
{M,10},asn1ct_check,
- {missing_ocft,contentType}}
+ illegal_table_constraint},
+ {structured_error,
+ {M,11},asn1ct_check,
+ invalid_table_constraint}
]} = run(P, Config),
ok.