diff options
author | Ingela Andin <[email protected]> | 2019-03-22 10:03:13 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-03-22 10:03:13 +0100 |
commit | d096ca2c0cebec816fa2e0386b7e5f0d8cd62a88 (patch) | |
tree | 799810afaf085beec0cce2d20bcba8324e791efa | |
parent | 5b62f4db7e6238f784c8f485baaa7f8fc61cd56c (diff) | |
parent | 7b73f5119b6a7bdadb2255b05dbd3463ec24e16f (diff) | |
download | otp-d096ca2c0cebec816fa2e0386b7e5f0d8cd62a88.tar.gz otp-d096ca2c0cebec816fa2e0386b7e5f0d8cd62a88.tar.bz2 otp-d096ca2c0cebec816fa2e0386b7e5f0d8cd62a88.zip |
Merge pull request #2159 from dotsimon/asn1_pedefs
ASN.1: fix various problems with value definitions
OTP-15697
-rw-r--r-- | lib/asn1/src/asn1ct_check.erl | 35 | ||||
-rw-r--r-- | lib/asn1/test/Makefile | 2 | ||||
-rw-r--r-- | lib/asn1/test/asn1_SUITE.erl | 12 | ||||
-rw-r--r-- | lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1 | 2 | ||||
-rw-r--r-- | lib/asn1/test/asn1_SUITE_data/DefaultOctetString.asn | 15 | ||||
-rw-r--r-- | lib/asn1/test/asn1_SUITE_data/SeqOfChoExt.asn1 | 27 | ||||
-rw-r--r-- | lib/asn1/test/testChoExtension.erl | 1 | ||||
-rw-r--r-- | lib/asn1/test/testDefaultOctetString.erl | 34 | ||||
-rw-r--r-- | lib/asn1/test/testSeqOfChoExt.erl | 15 |
9 files changed, 139 insertions, 4 deletions
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index 9ec0d93e93..9eec05abd1 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -1710,7 +1710,7 @@ check_value(S,#valuedef{pos=Pos,name=Name,type=Type, {valueset, check_type(S,#typedef{pos=Pos,name=Name,typespec=NewType},NewType)}; check_value(S, #valuedef{}=V) -> - ?dbg("check_value, V: ~p~n",[V0]), + ?dbg("check_value, V: ~p~n",[V]), case V of #valuedef{checked=true} -> V; @@ -1721,7 +1721,8 @@ check_value(S, #valuedef{}=V) -> check_valuedef(#state{recordtopname=TopName}=S0, V0) -> #valuedef{name=Name,type=Vtype0,value=Value,module=ModName} = V0, V = V0#valuedef{checked=true}, - Vtype = check_type(S0, #typedef{name=Name,typespec=Vtype0},Vtype0), + Vtype1 = expand_valuedef_type(Vtype0), + Vtype = check_type(S0, #typedef{name=Name,typespec=Vtype1},Vtype1), Def = Vtype#type.def, S1 = S0#state{tname=Def}, SVal = update_state(S1, ModName), @@ -1767,6 +1768,27 @@ check_valuedef(#state{recordtopname=TopName}=S0, V0) -> V#valuedef{value=normalize_value(SVal, Vtype, Value, TopName)} end. +expand_valuedef_type(#type{def=Seq}=Type) + when is_record(Seq,'SEQUENCE') -> + NewComponents = case Seq#'SEQUENCE'.components of + {R1,_Ext,R2} -> R1 ++ R2; + {Root,_Ext} -> Root; + Root -> take_only_rootset(Root) + end, + NewSeq = Seq#'SEQUENCE'{components = NewComponents}, + Type#type{def=NewSeq}; +expand_valuedef_type(#type{def=Set}=Type) + when is_record(Set,'SET') -> + NewComponents = case Set#'SET'.components of + {R1,_Ext,R2} -> R1 ++ R2; + {Root,_Ext} -> Root; + Root -> take_only_rootset(Root) + end, + NewSet = Set#'SET'{components = NewComponents}, + Type#type{def=NewSet}; +expand_valuedef_type(Type) -> + Type. + is_contextswitchtype(#typedef{name='EXTERNAL'})-> true; is_contextswitchtype(#typedef{name='EMBEDDED PDV'}) -> @@ -1998,7 +2020,8 @@ normalize_value(S, Type, {'DEFAULT',Value}, NameList) -> {'ENUMERATED',CType,_} -> normalize_enumerated(S,Value,CType); {'CHOICE',CType,NewNameList} -> - normalize_choice(S,Value,CType,NewNameList); + ChoiceComponents = get_choice_components(S, {'CHOICE',CType}), + normalize_choice(S,Value,ChoiceComponents,NewNameList); {'SEQUENCE',CType,NewNameList} -> normalize_sequence(S,Value,CType,NewNameList); {'SEQUENCE OF',CType,NewNameList} -> @@ -2140,6 +2163,9 @@ normalize_octetstring(S, Value) -> _ -> asn1_error(S, illegal_octet_string_value) end; + Val when is_binary(Val) -> + %% constant default value + Val; _ -> asn1_error(S, illegal_octet_string_value) end. @@ -2751,8 +2777,9 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) -> TempNewDef#newt{type={'SEQUENCE OF',check_sequenceof(S,Type,Components)}, tag= merge_tags(Tag,?TAG_CONSTRUCTED(?N_SEQUENCE))}; - {'CHOICE',Components} -> + {'CHOICE',_} = Choice-> Ct = maybe_illicit_implicit_tag(S, choice, Tag), + Components = get_choice_components(S, Choice), TempNewDef#newt{type={'CHOICE',check_choice(S,Type,Components)},tag=Ct}; Set when is_record(Set,'SET') -> RecordName= diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile index c38d1c6ebd..6ff4aa8d0f 100644 --- a/lib/asn1/test/Makefile +++ b/lib/asn1/test/Makefile @@ -60,6 +60,7 @@ MODULES= \ testSeqOf \ testSeqOfIndefinite \ testSeqOfCho \ + testSeqOfChoExt \ testSeqOfExternal \ testSeqOfTag \ testSetDefault \ @@ -72,6 +73,7 @@ MODULES= \ testSetTypeRefPrim \ testSetTypeRefSeq \ testSetTypeRefSet \ + testDefaultOctetString \ testChoiceIndefinite \ testSetOf \ testSetOfCho \ diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl index ab78678110..a88e464996 100644 --- a/lib/asn1/test/asn1_SUITE.erl +++ b/lib/asn1/test/asn1_SUITE.erl @@ -99,6 +99,7 @@ groups() -> testChoTypeRefPrim, testChoTypeRefSeq, testChoTypeRefSet, + testDefaultOctetString, testMultipleLevels, testOpt, testSeqDefault, @@ -118,6 +119,7 @@ groups() -> {group, [], [testSeqOf, testSeqOfIndefinite]}, % Uses 'Mvrasn*' testSeqOfCho, + testSeqOfChoExt, testSetDefault, testExtensionAdditionGroup, testSetOptional, @@ -430,6 +432,11 @@ testChoTypeRefSet(Config, Rule, Opts) -> asn1_test_lib:compile("ChoTypeRefSet", Config, [Rule|Opts]), testChoTypeRefSet:set(Rule). +testDefaultOctetString(Config) -> test(Config, fun testDefaultOctetString/3). +testDefaultOctetString(Config, Rule, Opts) -> + asn1_test_lib:compile("DefaultOctetString", Config, [Rule|Opts]), + testDefaultOctetString:dos(Rule). + testMultipleLevels(Config) -> test(Config, fun testMultipleLevels/3). testMultipleLevels(Config, Rule, Opts) -> asn1_test_lib:compile("MultipleLevels", Config, [Rule|Opts]), @@ -535,6 +542,11 @@ testSeqOfCho(Config, Rule, Opts) -> asn1_test_lib:compile("SeqOfCho", Config, [Rule|Opts]), testSeqOfCho:main(Rule). +testSeqOfChoExt(Config) -> test(Config, fun testSeqOfChoExt/3). +testSeqOfChoExt(Config, Rule, Opts) -> + asn1_test_lib:compile("SeqOfChoExt", Config, [Rule|Opts]), + testSeqOfChoExt:main(Rule). + testSeqOfIndefinite(Config) -> test(Config, fun testSeqOfIndefinite/3, [ber]). testSeqOfIndefinite(Config, Rule, Opts) -> diff --git a/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1 index 18473bae30..c488704196 100644 --- a/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1 +++ b/lib/asn1/test/asn1_SUITE_data/ChoExtension.asn1 @@ -41,4 +41,6 @@ ChoExt4 ::= CHOICE str OCTET STRING } +choExt1 ChoExt1 ::= int : 1 + END diff --git a/lib/asn1/test/asn1_SUITE_data/DefaultOctetString.asn b/lib/asn1/test/asn1_SUITE_data/DefaultOctetString.asn new file mode 100644 index 0000000000..076e965d58 --- /dev/null +++ b/lib/asn1/test/asn1_SUITE_data/DefaultOctetString.asn @@ -0,0 +1,15 @@ +DefaultOctetString +DEFINITIONS +AUTOMATIC TAGS + ::= +BEGIN +Dos ::= SEQUENCE { + opt [2] OCTET STRING (SIZE(2..4)) OPTIONAL, + def [10] OCTET STRING (SIZE (1)) DEFAULT '05'H +} + +dos Dos ::= { + opt '1234'H +} + +END diff --git a/lib/asn1/test/asn1_SUITE_data/SeqOfChoExt.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqOfChoExt.asn1 new file mode 100644 index 0000000000..51077754fd --- /dev/null +++ b/lib/asn1/test/asn1_SUITE_data/SeqOfChoExt.asn1 @@ -0,0 +1,27 @@ +SeqOfChoExt DEFINITIONS AUTOMATIC TAGS EXTENSIBILITY IMPLIED ::=
+BEGIN
+
+Seq2 ::= SEQUENCE {
+ octstr [PRIVATE 6] OCTET STRING OPTIONAL
+}
+
+SeqOfCho ::= SEQUENCE OF CHOICE {
+ nullable NULL,
+ seq2 Seq2
+}
+
+Seq1 ::= SEQUENCE {
+ int INTEGER,
+ soc SeqOfCho
+}
+
+seq1 Seq1 ::= {
+ int 10,
+ soc {
+ seq2 : {
+ octstr '01020A'H
+ }
+ }
+}
+
+END
diff --git a/lib/asn1/test/testChoExtension.erl b/lib/asn1/test/testChoExtension.erl index 4c632aab81..cfb28be5c7 100644 --- a/lib/asn1/test/testChoExtension.erl +++ b/lib/asn1/test/testChoExtension.erl @@ -28,6 +28,7 @@ extension(_Rules) -> roundtrip('ChoExt1', {bool,true}), roundtrip('ChoExt1', {int,33}), + {int, 1} = 'ChoExtension':choExt1(), %% A trick to encode with another compatible CHOICE type to test reception %% extension alternative diff --git a/lib/asn1/test/testDefaultOctetString.erl b/lib/asn1/test/testDefaultOctetString.erl new file mode 100644 index 0000000000..82cd5810e5 --- /dev/null +++ b/lib/asn1/test/testDefaultOctetString.erl @@ -0,0 +1,34 @@ +-module(testDefaultOctetString). + +-export([dos/1]). + +-include_lib("common_test/include/ct.hrl"). + +-record('Dos', { + opt = asn1_NOVALUE, + def = asn1_DEFAULT +}). + +-define(def_DEFAULT, <<5>>). + +dos(Rules) -> + %% test roundtrip default + E1 = roundtrip(#'Dos'{}, #'Dos'{def = ?def_DEFAULT}), + %% test the value dos defined in the .asn file + E2 = roundtrip('DefaultOctetString':dos()), + %% sanity test a fully specified SEQUENCE + E3 = roundtrip(#'Dos'{opt = <<1,2,3>>, def = <<6>>}), + %% test def is/isn't encoded according to the value + if Rules == ber -> + <<48, 0>> = E1, + <<48, 4, 16#82, 2, 16#12, 16#34>> = E2, + <<48, 8, 16#82, 3, 1, 2, 3, 16#8A, 1, 6>> = E3; + true -> + ignore + end, + ok. + +roundtrip(Value) -> + roundtrip(Value, Value). +roundtrip(Value, Exp) -> + asn1_test_lib:roundtrip('DefaultOctetString', 'Dos', Value, Exp). diff --git a/lib/asn1/test/testSeqOfChoExt.erl b/lib/asn1/test/testSeqOfChoExt.erl new file mode 100644 index 0000000000..1e72c60841 --- /dev/null +++ b/lib/asn1/test/testSeqOfChoExt.erl @@ -0,0 +1,15 @@ +-module(testSeqOfChoExt). + +-export([main/1]). + +%-record('Seq2', { octstr = asn1_NOVALUE }). +%-record('Seq1', { int, soc }). + +main(_Rules) -> + roundtrip('SeqOfChoExt':seq1()). + +roundtrip(Value) -> + roundtrip(Value, Value). +roundtrip(Value, Exp) -> + Type = element(1,Value), + asn1_test_lib:roundtrip('SeqOfChoExt', Type, Value, Exp). |