aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2014-10-28 14:47:50 +0100
committerBjörn Gustavsson <[email protected]>2015-01-12 11:40:25 +0100
commit0775ee9c7dc4957302a756b8b37cf94e372d3ecc (patch)
treedf646754c4e472fe6a17cd26a70a7348266e63e1
parent572b880ce6ad60ca0ad63aa9b4f8da01702834cf (diff)
downloadotp-0775ee9c7dc4957302a756b8b37cf94e372d3ecc.tar.gz
otp-0775ee9c7dc4957302a756b8b37cf94e372d3ecc.tar.bz2
otp-0775ee9c7dc4957302a756b8b37cf94e372d3ecc.zip
Improve handling of BIT STRING values
-rw-r--r--lib/asn1/src/asn1ct_check.erl50
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ValueTest.asn30
-rw-r--r--lib/asn1/test/error_SUITE.erl21
-rw-r--r--lib/asn1/test/testValueTest.erl11
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.