From 0775ee9c7dc4957302a756b8b37cf94e372d3ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Tue, 28 Oct 2014 14:47:50 +0100 Subject: Improve handling of BIT STRING values --- lib/asn1/src/asn1ct_check.erl | 50 ++++++++++++++--------------- lib/asn1/test/asn1_SUITE_data/ValueTest.asn | 30 +++++++++++++++++ lib/asn1/test/error_SUITE.erl | 21 +++++++++++- lib/asn1/test/testValueTest.erl | 11 +++++++ 4 files changed, 86 insertions(+), 26 deletions(-) diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index 828ebdac1c..4a67173064 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -2471,36 +2471,34 @@ normalize_bitstring(S, Value, Type)-> {bstring,String} when is_list(String) -> bstring_to_bitstring(String); #'Externalvaluereference'{} -> - get_normalized_value(S, Value, Type, - fun normalize_bitstring/3, []); - RecList when is_list(RecList) -> - F = fun(#'Externalvaluereference'{value=Name}) -> - case lists:keymember(Name, 1, Type) of - true -> Name; - false -> throw({error,false}) - end; - (Name) when is_atom(Name) -> - %% Already normalized. - Name; - (Other) -> - throw({error,Other}) - end, - try - lists:map(F, RecList) - catch - throw:{error,Reason} -> - asn1ct:warning("default value not " - "compatible with type definition ~p~n", - [Reason],S, - "default value not " - "compatible with type definition"), - Value + Val = get_referenced_value(S, Value), + normalize_bitstring(S, Val, Type); + {'ValueFromObject',{object,Obj},FieldNames} -> + case extract_field(S, Obj, FieldNames) of + #valuedef{value=Val} -> + normalize_bitstring(S, Val, Type); + _ -> + asn1_error(S, illegal_bitstring_value) end; + RecList when is_list(RecList) -> + [normalize_bs_item(S, Item, Type) || Item <- RecList]; Bs when is_bitstring(Bs) -> %% Already normalized. - Bs + Bs; + _ -> + asn1_error(S, illegal_bitstring_value) end. +normalize_bs_item(S, #'Externalvaluereference'{value=Name}, Type) -> + case lists:keymember(Name, 1, Type) of + true -> Name; + false -> asn1_error(S, illegal_bitstring_value) + end; +normalize_bs_item(_, Atom, _) when is_atom(Atom) -> + Atom; +normalize_bs_item(S, _, _) -> + asn1_error(S, illegal_bitstring_value). + hstring_to_binary(L) -> byte_align(hstring_to_bitstring(L)). @@ -6595,6 +6593,8 @@ asn1_error(S, Item, Error) -> format_error({already_defined,Name,PrevLine}) -> io_lib:format("the name ~p has already been defined at line ~p", [Name,PrevLine]); +format_error(illegal_bitstring_value) -> + "expecting a BIT STRING value"; format_error({illegal_class_name,Class}) -> io_lib:format("the class name '~s' is illegal (it must start with an uppercase letter and only contain uppercase letters, digits, or hyphens)", [Class]); format_error({illegal_instance_of,Class}) -> diff --git a/lib/asn1/test/asn1_SUITE_data/ValueTest.asn b/lib/asn1/test/asn1_SUITE_data/ValueTest.asn index 156d23ee62..b2c59d686a 100644 --- a/lib/asn1/test/asn1_SUITE_data/ValueTest.asn +++ b/lib/asn1/test/asn1_SUITE_data/ValueTest.asn @@ -110,4 +110,34 @@ otherOctetString OCTET STRING ::= someOctetString os-1 OCTET STRING ::= os-2 os-2 OCTET STRING ::= os-holder-1.&os +-- Recursive BIT STRING definitions. + +BS-HOLDER ::= CLASS { + &id INTEGER UNIQUE, + &bs BIT STRING, + &named-bs NamedBsType +} WITH SYNTAX { + ID &id BS &bs NAMED-BS &named-bs +} +bs-holder-1 BS-HOLDER ::= { ID 1 BS '101'B NAMED-BS {a,c} } + +NamedBsType ::= BIT STRING {a(0),b(1),c(2)} +BsSeq ::= SEQUENCE { + a BIT STRING, + b NamedBsType +} + +someBitString BIT STRING ::= '101101'B + +bsSeq1 BsSeq ::= { a someBitString, b someNamedBs } +bsSeq2 BsSeq ::= { a otherBitString, b someOtherNamedBs } +bsSeq3 BsSeq ::= { a bs-holder-1.&bs, b bs-holder-1.&named-bs } + +otherBitString BIT STRING ::= someBitString +bsFromObjectInd BIT STRING ::= bsFromObject +bsFromObject BIT STRING ::= bs-holder-1.&bs + +someOtherNamedBs NamedBsType ::= someNamedBs +someNamedBs NamedBsType ::= {c} + END diff --git a/lib/asn1/test/error_SUITE.erl b/lib/asn1/test/error_SUITE.erl index 4534abc0c4..d83131db92 100644 --- a/lib/asn1/test/error_SUITE.erl +++ b/lib/asn1/test/error_SUITE.erl @@ -601,6 +601,13 @@ values(Config) -> " int6 INTEGER ::= holder-2.&undefined-field\n" " int7 INTEGER ::= holder-2.&UndefinedField.&id\n" + " bs1 BIT STRING ::= 42\n" + " bs2 BIT STRING ::= {a,b}\n" + " bs3 BIT STRING {a(0),z(25)} ::= {a,b}\n" + " bs4 BIT STRING {a(0),z(25)} ::= int\n" + " bs5 BIT STRING ::= holder-2.&str\n" + " bs6 BIT STRING ::= holder-2.&obj\n" + " HOLDER ::= CLASS {\n" " &str IA5String,\n" " &obj HOLDER OPTIONAL\n" @@ -638,7 +645,19 @@ values(Config) -> {structured_error,{M,17},asn1ct_check, {undefined_field,'undefined-field'}}, {structured_error,{M,18},asn1ct_check, - {undefined_field,'UndefinedField'}} + {undefined_field,'UndefinedField'}}, + {structured_error,{M,19},asn1ct_check, + illegal_bitstring_value}, + {structured_error,{M,20},asn1ct_check, + illegal_bitstring_value}, + {structured_error,{M,21},asn1ct_check, + illegal_bitstring_value}, + {structured_error,{M,22},asn1ct_check, + illegal_bitstring_value}, + {structured_error,{M,23},asn1ct_check, + illegal_bitstring_value}, + {structured_error,{M,24},asn1ct_check, + illegal_bitstring_value} ] } = run(P, Config), ok. diff --git a/lib/asn1/test/testValueTest.erl b/lib/asn1/test/testValueTest.erl index d1532c3ef0..8a8e973621 100644 --- a/lib/asn1/test/testValueTest.erl +++ b/lib/asn1/test/testValueTest.erl @@ -88,6 +88,17 @@ main() -> <<16#40,16#41,16#FF>> = M:'os-1'(), <<16#40,16#41,16#FF>> = M:'os-2'(), + %% Recursive BIT STRING definitions. + {'BsSeq',<<2#101101:6>>,[c]} = M:bsSeq1(), + {'BsSeq',<<2#101101:6>>,[c]} = M:bsSeq2(), + {'BsSeq',<<2#101:3>>,[a,c]} = M:bsSeq3(), + <<2#101101:6>> = M:someBitString(), + <<2#101101:6>> = M:otherBitString(), + <<2#101:3>> = M:bsFromObject(), + <<2#101:3>> = M:bsFromObjectInd(), + [c] = M:someNamedBs(), + [c] = M:someOtherNamedBs(), + ok. -- cgit v1.2.3