aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asn1')
-rw-r--r--lib/asn1/src/asn1ct.erl12
-rw-r--r--lib/asn1/src/asn1ct_check.erl69
-rw-r--r--lib/asn1/src/asn1ct_gen.erl6
-rw-r--r--lib/asn1/src/asn1ct_table.erl34
-rw-r--r--lib/asn1/src/asn1ct_tok.erl2
-rw-r--r--lib/asn1/src/asn1ct_value.erl2
-rw-r--r--lib/asn1/test/asn1_SUITE_data/EnumExt.asn12
-rw-r--r--lib/asn1/test/error_SUITE.erl29
-rw-r--r--lib/asn1/test/testEnumExt.erl4
9 files changed, 88 insertions, 72 deletions
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl
index 531a4935fe..30f493a2df 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -1040,7 +1040,7 @@ get_file_list1(Stream,Dir,Includes,Acc) ->
Ret = io:get_line(Stream,''),
case Ret of
eof ->
- file:close(Stream),
+ ok = file:close(Stream),
lists:reverse(Acc);
FileName ->
SuffixedNameList =
@@ -1926,8 +1926,9 @@ read_config_file(ModuleName) ->
Includes = [I || {i,I} <- Options],
read_config_file1(ModuleName,Includes);
{error,Reason} ->
- file:format_error(Reason),
- throw({error,{"error reading asn1 config file",Reason}})
+ Error = "error reading asn1 config file: " ++
+ file:format_error(Reason),
+ throw({error,Error})
end.
read_config_file1(ModuleName,[]) ->
case filename:extension(ModuleName) of
@@ -1945,8 +1946,9 @@ read_config_file1(ModuleName,[H|T]) ->
{error,enoent} ->
read_config_file1(ModuleName,T);
{error,Reason} ->
- file:format_error(Reason),
- throw({error,{"error reading asn1 config file",Reason}})
+ Error = "error reading asn1 config file: " ++
+ file:format_error(Reason),
+ throw({error,Error})
end.
get_config_info(CfgList,InfoType) ->
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index f94f3b56bc..b9f2cb876a 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.erl
@@ -2464,7 +2464,7 @@ normalize_value(S0, Type, {'DEFAULT',Value}, NameList) ->
{'BIT STRING',CType,_} ->
normalize_bitstring(S,Value,CType);
{'OCTET STRING',CType,_} ->
- normalize_octetstring(S,Value,CType);
+ normalize_octetstring(S0, Value, CType);
{'NULL',_CType,_} ->
%%normalize_null(Value);
'NULL';
@@ -2612,20 +2612,9 @@ normalize_octetstring(S,Value,CType) ->
fun normalize_octetstring/3,[]);
{Name,String} when is_atom(Name) ->
normalize_octetstring(S,String,CType);
- List when is_list(List) ->
- %% check if list elements are valid octet values
- lists:map(fun([])-> ok;
- (H)when H > 255->
- asn1ct:warning("not legal octet value ~p in OCTET STRING, ~p~n",
- [H,List],S,
- "not legal octet value ~p in OCTET STRING");
- (_)-> ok
- end, List),
- List;
- Other ->
- asn1ct:warning("unknown default value ~p~n",[Other],S,
- "unknown default value"),
- Value
+ _ ->
+ Item = S#state.value,
+ throw(asn1_error(S, Item, illegal_octet_string_value))
end.
normalize_objectidentifier(S, Value) ->
@@ -2642,16 +2631,19 @@ normalize_objectdescriptor(Value) ->
normalize_real(Value) ->
Value.
-normalize_enumerated(S, Id, {Base,Ext}) ->
+normalize_enumerated(S, Id0, NNL) ->
+ {Id,_} = lookup_enum_value(S, Id0, NNL),
+ Id.
+
+lookup_enum_value(S, Id, {Base,Ext}) ->
%% Extensible ENUMERATED.
- normalize_enumerated(S, Id, Base++Ext);
-normalize_enumerated(S, #'Externalvaluereference'{value=Id},
- NamedNumberList) ->
- normalize_enumerated(S, Id, NamedNumberList);
-normalize_enumerated(S, Id, NamedNumberList) when is_atom(Id) ->
- case lists:keymember(Id, 1, NamedNumberList) of
- true ->
- Id;
+ lookup_enum_value(S, Id, Base++Ext);
+lookup_enum_value(S, #'Externalvaluereference'{value=Id}, NNL) ->
+ lookup_enum_value(S, Id, NNL);
+lookup_enum_value(S, Id, NNL) when is_atom(Id) ->
+ case lists:keyfind(Id, 1, NNL) of
+ {_,_}=Ret ->
+ Ret;
false ->
throw(asn1_error(S, S#state.value, {undefined,Id}))
end.
@@ -3088,7 +3080,6 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
Ct=maybe_illicit_implicit_tag(open_type,Tag),
TempNewDef#newt{type='ASN1_OPEN_TYPE',tag=Ct};
'INTEGER' ->
- check_integer(S,[],Constr),
TempNewDef#newt{tag=
merge_tags(Tag,?TAG_PRIMITIVE(?N_INTEGER))};
@@ -3786,8 +3777,9 @@ resolv_value(S,Val) ->
resolv_value1(S,Id).
resolv_value1(S, ERef = #'Externalvaluereference'{value=Name}) ->
- case catch resolve_namednumber(S,S#state.type,Name) of
- V when is_integer(V) -> V;
+ case catch resolve_namednumber(S, S#state.type, Name) of
+ V when is_integer(V) ->
+ V;
_ ->
case get_referenced_type(S,ERef) of
{Err,_Reason} when Err == error; Err == 'EXIT' ->
@@ -3840,21 +3832,20 @@ resolve_value_from_object(S,Object,FieldName) ->
end.
-
resolve_namednumber(S,#typedef{typespec=Type},Name) ->
case Type#type.def of
{'ENUMERATED',NameList} ->
- NamedNumberList=check_enumerated(S,NameList,Type#type.constraint),
- N = normalize_enumerated(S,Name,NamedNumberList),
- {value,{_,V}} = lists:keysearch(N,1,NamedNumberList),
- V;
+ resolve_namednumber_1(S, Name, NameList, Type);
{'INTEGER',NameList} ->
- NamedNumberList = check_enumerated(S,NameList,Type#type.constraint),
- {value,{_,V}} = lists:keysearch(Name,1,NamedNumberList),
- V;
+ resolve_namednumber_1(S, Name, NameList, Type);
_ ->
not_enumerated
end.
+
+resolve_namednumber_1(S, Name, NameList, Type) ->
+ NamedNumberList = check_enumerated(S, NameList, Type#type.constraint),
+ {_,N} = lookup_enum_value(S, Name, NamedNumberList),
+ N.
check_constraints(S,[{'ContainedSubtype',Type} | Rest], Acc) ->
{RefMod,CTDef} = get_referenced_type(S,Type#type.def),
@@ -3935,9 +3926,9 @@ check_constraint(S,{simpletable,Type}) ->
#'Externaltypereference'{} ->
ERef = check_externaltypereference(S,C),
{simpletable,ERef#'Externaltypereference'.type};
- #type{def=#'Externaltypereference'{type=T}} ->
- check_externaltypereference(S,C#type.def),
- {simpletable,T};
+ #type{def=#'Externaltypereference'{}=ExtTypeRef} ->
+ ERef = check_externaltypereference(S, ExtTypeRef),
+ {simpletable,ERef#'Externaltypereference'.type};
{valueset,#type{def=ERef=#'Externaltypereference'{}}} -> % this is an object set
{_,TDef} = get_referenced_type(S,ERef),
case TDef#typedef.typespec of
@@ -6811,6 +6802,8 @@ asn1_error(#state{mname=Where}, 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_octet_string_value) ->
+ "expecting a bstring or an hstring as value for an OCTET STRING";
format_error({invalid_fields,Fields,Obj}) ->
io_lib:format("invalid ~s in ~p", [format_fields(Fields),Obj]);
format_error({missing_mandatory_fields,Fields,Obj}) ->
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index 71d870b4ce..4707e517b4 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -71,7 +71,7 @@ pgen_module(OutFile,Erules,Module,
HrlGenerated = pgen_hrl(Erules,Module,TypeOrVal,Options,Indent),
asn1ct_name:start(),
ErlFile = lists:concat([OutFile,".erl"]),
- open_output_file(ErlFile),
+ _ = open_output_file(ErlFile),
asn1ct_func:start_link(),
gen_head(Erules,Module,HrlGenerated),
pgen_exports(Erules,Module,TypeOrVal),
@@ -190,7 +190,7 @@ pgen_check_defaultval(Erules,Module) ->
"********~n~n",[X])
end,
lists:foreach(Fun,CheckObjects),
- file:close(IoDevice);
+ ok = file:close(IoDevice);
_ -> ok
end,
gen_check_defaultval(Erules,Module,CheckObjects).
@@ -1124,7 +1124,7 @@ pgen_info() ->
open_hrl(OutFile,Module) ->
File = lists:concat([OutFile,".hrl"]),
- open_output_file(File),
+ _ = open_output_file(File),
gen_hrlhead(Module).
%% EMIT functions ************************
diff --git a/lib/asn1/src/asn1ct_table.erl b/lib/asn1/src/asn1ct_table.erl
index a5eb6d0413..2eca80eda3 100644
--- a/lib/asn1/src/asn1ct_table.erl
+++ b/lib/asn1/src/asn1ct_table.erl
@@ -22,34 +22,25 @@
%% Table abstraction module for ASN.1 compiler
-export([new/1]).
--export([new/2]).
-export([new_reuse/1]).
--export([new_reuse/2]).
-export([exists/1]).
-export([size/1]).
-export([insert/2]).
-export([lookup/2]).
-export([match/2]).
-export([to_list/1]).
--export([delete/1]). % TODO: Remove (since we run in a separate process)
+-export([delete/1]).
-%% Always creates a new table
-new(Table) -> new(Table, []).
-new(Table, Options) ->
- TableId = case get(Table) of
- undefined ->
- ets:new(Table, Options);
- _ ->
- delete(Table),
- ets:new(Table, Options)
- end,
+%% Always create a new table.
+new(Table) ->
+ undefined = get(Table), %Assertion.
+ TableId = ets:new(Table, []),
put(Table, TableId).
-%% Only create it if it doesn't exist yet
-new_reuse(Table) -> new_reuse(Table, []).
-new_reuse(Table, Options) ->
- not exists(Table) andalso new(Table, Options).
+%% Only create it if it doesn't exist yet.
+new_reuse(Table) ->
+ not exists(Table) andalso new(Table).
exists(Table) -> get(Table) =/= undefined.
@@ -63,14 +54,17 @@ match(Table, MatchSpec) -> ets:match(get(Table), MatchSpec).
to_list(Table) -> ets:tab2list(get(Table)).
+%% Deleting tables is no longer strictly necessary since each compilation
+%% runs in separate process, but it will reduce memory consumption
+%% especially when many compilations are run in parallel.
+
delete(Tables) when is_list(Tables) ->
[delete(T) || T <- Tables],
true;
delete(Table) when is_atom(Table) ->
- case get(Table) of
+ case erase(Table) of
undefined ->
true;
TableId ->
- ets:delete(TableId),
- erase(Table)
+ ets:delete(TableId)
end.
diff --git a/lib/asn1/src/asn1ct_tok.erl b/lib/asn1/src/asn1ct_tok.erl
index 85199c65ec..33f4379173 100644
--- a/lib/asn1/src/asn1ct_tok.erl
+++ b/lib/asn1/src/asn1ct_tok.erl
@@ -36,7 +36,7 @@ process(Stream,Lno,R) ->
process(io:get_line(Stream, ''), Stream,Lno+1,R).
process(eof, Stream,Lno,R) ->
- file:close(Stream),
+ ok = file:close(Stream),
lists:flatten(lists:reverse([{'$end',Lno}|R]));
diff --git a/lib/asn1/src/asn1ct_value.erl b/lib/asn1/src/asn1ct_value.erl
index a86c963b9d..be8b967cf0 100644
--- a/lib/asn1/src/asn1ct_value.erl
+++ b/lib/asn1/src/asn1ct_value.erl
@@ -352,7 +352,7 @@ random_unnamed_bit_string(M, C) ->
random(Upper) ->
{A1,A2,A3} = erlang:now(),
- random:seed(A1,A2,A3),
+ _ = random:seed(A1, A2, A3),
random:uniform(Upper).
size_random(C) ->
diff --git a/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1 b/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1
index 8dc5f3d7e1..74fa97e7aa 100644
--- a/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/EnumExt.asn1
@@ -18,6 +18,8 @@ Ext1 ::= ENUMERATED {
magenta(9)
}
+SubExt1 ::= Ext1 ( blue | orange | black )
+
Noext ::= ENUMERATED {
blue(0),
red(1),
diff --git a/lib/asn1/test/error_SUITE.erl b/lib/asn1/test/error_SUITE.erl
index 6451f81c01..930b44cea6 100644
--- a/lib/asn1/test/error_SUITE.erl
+++ b/lib/asn1/test/error_SUITE.erl
@@ -19,7 +19,7 @@
-module(error_SUITE).
-export([suite/0,all/0,groups/0,
- already_defined/1,enumerated/1,objects/1]).
+ already_defined/1,enumerated/1,objects/1,values/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -29,9 +29,11 @@ all() ->
[{group,p}].
groups() ->
- [{p,parallel(),[already_defined,
- enumerated,
- objects]}].
+ [{p,parallel(),
+ [already_defined,
+ enumerated,
+ objects,
+ values]}].
parallel() ->
case erlang:system_info(schedulers) > 1 of
@@ -138,6 +140,25 @@ objects(Config) ->
} = run(P, Config),
ok.
+values(Config) ->
+ M = 'Values',
+ P = {M,
+ <<"Values DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ " os1 OCTET STRING ::= \"abc\"\n"
+ " os2 OCTET STRING ::= 42\n"
+ " os3 OCTET STRING ::= { 1, 3 }\n"
+ "END\n">>},
+ {error,
+ [
+ {structured_error,{M,2},asn1ct_check,
+ illegal_octet_string_value},
+ {structured_error,{M,3},asn1ct_check,
+ illegal_octet_string_value},
+ {structured_error,{M,4},asn1ct_check,
+ illegal_octet_string_value}
+ ]
+ } = run(P, Config),
+ ok.
run({Mod,Spec}, Config) ->
diff --git a/lib/asn1/test/testEnumExt.erl b/lib/asn1/test/testEnumExt.erl
index c66adaf949..878518be11 100644
--- a/lib/asn1/test/testEnumExt.erl
+++ b/lib/asn1/test/testEnumExt.erl
@@ -59,6 +59,10 @@ main(ber) ->
common(ber).
common(Erule) ->
+ roundtrip('SubExt1', blue),
+ roundtrip('SubExt1', orange),
+ roundtrip('SubExt1', black),
+
roundtrip('Seq', {'Seq',blue,42}),
roundtrip('Seq', {'Seq',red,42}),
roundtrip('Seq', {'Seq',green,42}),