aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asn1')
-rw-r--r--lib/asn1/src/asn1ct_check.erl145
-rw-r--r--lib/asn1/test/Makefile1
-rw-r--r--lib/asn1/test/asn1_SUITE.erl9
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Constraints.py16
-rw-r--r--lib/asn1/test/asn1_SUITE_data/InfObjExtract.asn151
-rw-r--r--lib/asn1/test/asn1_SUITE_data/ValueTest.asn22
-rw-r--r--lib/asn1/test/error_SUITE.erl73
-rw-r--r--lib/asn1/test/testConstraints.erl9
-rw-r--r--lib/asn1/test/testInfObjExtract.erl47
-rw-r--r--lib/asn1/test/testValueTest.erl20
10 files changed, 324 insertions, 69 deletions
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index 3f32a77c1d..fc15cfbb88 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.erl
@@ -1160,10 +1160,14 @@ check_object_list(S,ClassRef,[ObjOrSet|Objs],Acc) ->
{RefedMod,ObjName,
#'Object'{def=Def}} = check_referenced_object(S,ObjRef),
check_object_list(S,ClassRef,Objs,[{{RefedMod,ObjName},Def}|Acc]);
- {'ValueFromObject',{_,Object},FieldName} ->
- {_,Def} = get_referenced_type(S,Object),
- TypeDef = get_fieldname_element(S,Def,FieldName),
- (TypeDef#typedef.typespec)#'ObjectSet'.set;
+ {'ValueFromObject',{object,Object},FieldNames} ->
+ case extract_field(S, Object, FieldNames) of
+ #'Object'{def=Def} ->
+ check_object_list(S, ClassRef, Objs,
+ [{{no_mod,no_name},Def}|Acc]);
+ _ ->
+ asn1_error(S, S#state.type, illegal_object)
+ end;
ObjSet when is_record(ObjSet,type) ->
ObjSetDef =
case ObjSet#type.def of
@@ -1256,13 +1260,45 @@ osfo_intersection(InterSect,ObjList) ->
Res
end.
-%% get_fieldname_element/3
-%% gets the type/value/object/... of the referenced element in FieldName
-%% FieldName is a list and may have more than one element.
-%% Each element in FieldName can be either {typefieldreference,AnyFieldName}
-%% or {valuefieldreference,AnyFieldName}
-%% Def is the def of the first object referenced by FieldName
-get_fieldname_element(S,Def,[{_RefType,FieldName}]) when is_record(Def,typedef) ->
+%% get_type_from_object(State, ObjectOrObjectSet, [{RefType,FieldName}]) ->
+%% Type
+get_type_from_object(S, Object, FieldNames)
+ when is_record(Object, 'Externaltypereference');
+ is_record(Object, 'Externalvaluereference') ->
+ extract_field(S, Object, FieldNames).
+
+%% get_value_from_object(State, ObjectOrObjectSet, [{RefType,FieldName}]) ->
+%% UntaggedValue
+get_value_from_object(S, Def, FieldNames) ->
+ case extract_field(S, Def, FieldNames) of
+ #valuedef{value=Val} ->
+ Val;
+ _ ->
+ asn1_error(S, Def, illegal_value)
+ end.
+
+%% extract_field(State, ObjectOrObjectSet, [{RefType,FieldName}])
+%% RefType = typefieldreference | valuefieldreference
+%%
+%% Get the type, value, object, object set, or value set from the
+%% referenced object or object set. The list of field name tuples
+%% may have more than one element. All field names but the last
+%% refers to either an object or object set.
+
+extract_field(S, Def0, FieldNames) ->
+ {_,Def1} = get_referenced_type(S, Def0),
+ Def2 = check_object(S, Def1, Def1#typedef.typespec),
+ Def = Def1#typedef{typespec=Def2},
+ get_fieldname_element(S, Def, FieldNames).
+
+%% get_fieldname_element(State, Element, [{RefType,FieldName}]
+%% RefType = typefieldreference | valuefieldreference
+%%
+%% Get the type, value, object, object set, or value set from the referenced
+%% element. The list of field name tuples may have more than one element.
+%% All field names but the last refers to either an object or object set.
+
+get_fieldname_element(S, #typedef{}=Def, [{_RefType,FieldName}]) ->
{_,_,ObjComps} = (Def#typedef.typespec)#'Object'.def,
check_fieldname_element(S,lists:keysearch(FieldName,1,ObjComps));
get_fieldname_element(S,Def,[{_RefType,FieldName}|Rest])
@@ -1311,6 +1347,8 @@ check_fieldname_element(S, #valuedef{}=VDef) ->
NewDef = #typedef{checked=C,pos=Pos,name=N,typespec=NewSpec},
check_fieldname_element(S, NewDef)
end;
+check_fieldname_element(_S, {value_tag,Val}) ->
+ #valuedef{value=Val};
check_fieldname_element(S,Eref)
when is_record(Eref,'Externaltypereference');
is_record(Eref,'Externalvaluereference') ->
@@ -1968,13 +2006,16 @@ get_objectset_def(_S,ObjFieldSetting={{'SingleValue',_},_},CField) ->
%% a Union of defined objects
?dbg("objectsetfield, SingleValue~n",[]),
union_of_defed_objs(CField,ObjFieldSetting);
-get_objectset_def(S,{object,_,[#type{def={'TypeFromObject',
- {object,RefedObj},
- FieldName}}]},_CField) ->
- %% This case occurs when an ObjectSetFromObjects
- %% production is used
- {_M,Def} = get_referenced_type(S,RefedObj),
- get_fieldname_element(S,Def,FieldName);
+get_objectset_def(S, {object,_,
+ [#type{def={'TypeFromObject',
+ {object,Object},
+ FieldNames}}]},
+ CField) ->
+ %% This case occurs when an ObjectSetFromObject
+ %% production is used.
+ Def = #typedef{checked=true,
+ typespec=extract_field(S, Object, FieldNames)},
+ get_objectset_def2(S, Def, CField);
get_objectset_def(S,{object,_,[{setting,_,ERef}]},CField)
when is_record(ERef,'Externaltypereference') ->
{_,T} = get_referenced_type(S,ERef),
@@ -2496,6 +2537,13 @@ normalize_integer(S, #'Externalvaluereference'{value=Name}=Ref, NNL) ->
asn1_error(S, S#state.value, illegal_integer_value)
end
end;
+normalize_integer(S, {'ValueFromObject',{object,Obj},FieldNames}, _) ->
+ case extract_field(S, Obj, FieldNames) of
+ #valuedef{value=Val} when is_integer(Val) ->
+ Val;
+ _ ->
+ asn1_error(S, S#state.value, illegal_integer_value)
+ end;
normalize_integer(#state{value=Val}=S, _, _) ->
asn1_error(S, Val, illegal_integer_value).
@@ -3357,13 +3405,6 @@ get_innertag(_S,#'ObjectClassFieldType'{type=Type}) ->
_ -> []
end.
-get_type_from_object(S,Object,TypeField)
- when is_record(Object,'Externaltypereference');
- is_record(Object,'Externalvaluereference') ->
- {_,ObjectDef} = get_referenced_type(S,Object),
- ObjSpec = check_object(S,ObjectDef,ObjectDef#typedef.typespec),
- get_fieldname_element(S,ObjectDef#typedef{typespec=ObjSpec},TypeField).
-
%% get_class_def(S, Type) -> #classdef{} | 'none'.
get_class_def(S, #typedef{typespec=#type{def=#'Externaltypereference'{}=Eref}}) ->
{_,NextDef} = get_referenced_type(S, Eref),
@@ -3708,44 +3749,28 @@ resolv_value1(S, {gt,V}) ->
case resolv_value1(S, V) of
Int when is_integer(Int) ->
Int + 1;
- Other ->
- throw({error,{asn1,{not_integer_value,Other}}})
+ _Other ->
+ asn1_error(S, S#state.type, illegal_integer_value)
end;
resolv_value1(S, {lt,V}) ->
case resolv_value1(S, V) of
Int when is_integer(Int) ->
Int - 1;
- Other ->
- throw({error,{asn1,{not_integer_value,Other}}})
+ _Other ->
+ asn1_error(S, S#state.type, illegal_integer_value)
end;
-resolv_value1(S,{'ValueFromObject',{object,Object},[{valuefieldreference,
- FieldName}]}) ->
- %% FieldName can hold either a fixed-type value or a variable-type value
- %% Object is a DefinedObject, i.e. a #'Externaltypereference'
- resolve_value_from_object(S,Object,FieldName);
+resolv_value1(S, {'ValueFromObject',{object,Object},FieldName}) ->
+ get_value_from_object(S, Object, FieldName);
resolv_value1(_,#valuedef{checked=true,value=V}) ->
V;
-resolv_value1(S,#valuedef{type=_T,
- value={'ValueFromObject',{object,Object},
- [{valuefieldreference,
- FieldName}]}}) ->
- resolve_value_from_object(S,Object,FieldName);
+resolv_value1(S, #valuedef{value={'ValueFromObject',
+ {object,Object},FieldName}}) ->
+ get_value_from_object(S, Object, FieldName);
resolv_value1(S,VDef = #valuedef{}) ->
#valuedef{value=Val} = check_value(S,VDef),
Val;
resolv_value1(_,V) ->
V.
-resolve_value_from_object(S,Object,FieldName) ->
- {_,ObjTDef} = get_referenced_type(S,Object),
- TS = check_object(S,ObjTDef,ObjTDef#typedef.typespec),
- {_,_,Components} = TS#'Object'.def,
- case lists:keysearch(FieldName,1,Components) of
- {value,{_,#valuedef{value=Val}}} ->
- Val;
- _ ->
- error({value,"illegal value in constraint",S})
- end.
-
resolve_namednumber(S,#typedef{typespec=Type},Name) ->
case Type#type.def of
@@ -3874,19 +3899,9 @@ check_constraint(S,{simpletable,Type}) ->
#'ObjectSet'{} ->
io:format("ALERT: simpletable forbidden case!~n",[]),
{simpletable,check_object(S,Type,C)};
- {'ValueFromObject',{_,ORef},FieldName} ->
- %% This is an ObjectFromObject
- {_,Object} = get_referenced_type(S,ORef),
- ChObject = check_object(S,Object,
- Object#typedef.typespec),
- ObjFromObj=
- get_fieldname_element(S,Object#typedef{
- typespec=ChObject},
- FieldName),
- {simpletable,ObjFromObj};
-%% ObjFromObj#typedef{checked=true,typespec=
-%% check_object(S,ObjFromObj,
-%% ObjFromObj#typedef.typespec)}};
+ {'ValueFromObject',{_,Object},FieldNames} ->
+ %% This is an ObjectFromObject.
+ {simpletable,extract_field(S, Object, FieldNames)};
_ ->
check_type(S,S#state.tname,Type),%% this seems stupid.
OSName = Def#'Externaltypereference'.type,
@@ -6692,10 +6707,14 @@ format_error({illegal_instance_of,Class}) ->
[Class]);
format_error(illegal_integer_value) ->
"expecting an integer value";
+format_error(illegal_object) ->
+ "expecting an object";
format_error(illegal_octet_string_value) ->
"expecting a bstring or an hstring as value for an OCTET STRING";
format_error({illegal_typereference,Name}) ->
io_lib:format("'~p' is used as a typereference, but does not start with an uppercase letter", [Name]);
+format_error(illegal_value) ->
+ "expected a value";
format_error({invalid_fields,Fields,Obj}) ->
io_lib:format("invalid ~s in ~p", [format_fields(Fields),Obj]);
format_error({invalid_bit_number,Bit}) ->
diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile
index 2c9d06cc0a..ff2ae204dc 100644
--- a/lib/asn1/test/Makefile
+++ b/lib/asn1/test/Makefile
@@ -78,6 +78,7 @@ MODULES= \
testEnumExt \
testInfObjectClass \
testInfObj \
+ testInfObjExtract \
testParameterizedInfObj \
testFragmented \
testMergeCompile \
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
index fef2981b00..668a8a2648 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -135,6 +135,7 @@ groups() ->
testChoiceIndefinite,
per_open_type,
testInfObjectClass,
+ testInfObjExtract,
testParam,
testFragmented,
testMergeCompile,
@@ -766,6 +767,11 @@ testInfObjectClass(Config, Rule, Opts) ->
testInfObjectClass:main(Rule),
testInfObj:main(Rule).
+testInfObjExtract(Config) -> test(Config, fun testInfObjExtract/3).
+testInfObjExtract(Config, Rule, Opts) ->
+ asn1_test_lib:compile("InfObjExtract", Config, [Rule|Opts]),
+ testInfObjExtract:main().
+
testParam(Config) ->
test(Config, fun testParam/3, [ber,{ber,[der]},per,uper]).
testParam(Config, Rule, Opts) ->
@@ -840,8 +846,7 @@ testContextSwitchingTypes(Config, Rule, Opts) ->
testTypeValueNotation(Config) -> test(Config, fun testTypeValueNotation/3).
testTypeValueNotation(Config, Rule, Opts) ->
- asn1_test_lib:compile_all(["SeqTypeRefPrim", "ValueTest"], Config,
- [Rule|Opts]),
+ asn1_test_lib:compile("SeqTypeRefPrim", Config, [Rule|Opts]),
testTypeValueNotation:main(Rule, Opts).
testValueTest(Config) -> test(Config, fun testValueTest/3).
diff --git a/lib/asn1/test/asn1_SUITE_data/Constraints.py b/lib/asn1/test/asn1_SUITE_data/Constraints.py
index 3495cd841b..bee619348a 100644
--- a/lib/asn1/test/asn1_SUITE_data/Constraints.py
+++ b/lib/asn1/test/asn1_SUITE_data/Constraints.py
@@ -144,5 +144,21 @@ NonOverlapping ::= INTEGER (7280..7560 |
23000..24000 |
24960..26900)
+--
+-- Test INTEGER constraints from fields in objects.
+--
+
+INT-HOLDER ::= CLASS {
+ &id INTEGER UNIQUE,
+ &obj INT-HOLDER OPTIONAL
+} WITH SYNTAX {
+ ID &id
+ [OBJ &obj]
+}
+
+int-holder-1 INT-HOLDER ::= { ID 2 }
+int-holder-2 INT-HOLDER ::= { ID 4 OBJ int-holder-1 }
+
+IntObjectConstr ::= INTEGER (int-holder-2.&obj.&id..int-holder-2.&id)
END
diff --git a/lib/asn1/test/asn1_SUITE_data/InfObjExtract.asn1 b/lib/asn1/test/asn1_SUITE_data/InfObjExtract.asn1
new file mode 100644
index 0000000000..4a8889f940
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/InfObjExtract.asn1
@@ -0,0 +1,51 @@
+InfObjExtract DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+DATA-CLASS ::= CLASS {
+ &id INTEGER UNIQUE,
+ &Type
+} WITH SYNTAX {
+ ID &id
+ TYPE &Type
+}
+
+data-object-1 DATA-CLASS ::= { ID 1 TYPE BOOLEAN }
+data-object-2 DATA-CLASS ::= { ID 2 TYPE OCTET STRING }
+data-object-3 DATA-CLASS ::= { ID 3 TYPE BIT STRING }
+
+ObjSet DATA-CLASS ::= {
+ holder-object-1.&obj |
+ data-object-2 |
+ data-object-3,
+ ...
+}
+
+holder-object-1 HOLDER-CLASS ::= {
+ OBJ data-object-1
+}
+
+holder-object-2 HOLDER-CLASS ::= {
+ OBJ-SET {data-object-1}
+}
+
+holder-object-3 HOLDER-CLASS ::= {
+ OBJ-SET {holder-object-2.&ObjSet}
+}
+
+HOLDER-CLASS ::= CLASS {
+ &obj DATA-CLASS OPTIONAL,
+ &ObjSet DATA-CLASS OPTIONAL
+} WITH SYNTAX {
+ [OBJ &obj]
+ [OBJ-SET &ObjSet]
+}
+
+TestSeq{DATA-CLASS:ObjectSet} ::= SEQUENCE {
+ id DATA-CLASS.&id ({ObjectSet}),
+ data DATA-CLASS.&Type ({ObjectSet}{@id})
+}
+
+DataSeq-1 ::= TestSeq{ {ObjSet} }
+DataSeq-2 ::= TestSeq{ {holder-object-3.&ObjSet} }
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/ValueTest.asn b/lib/asn1/test/asn1_SUITE_data/ValueTest.asn
index 8db2fcf17d..51da9d8afb 100644
--- a/lib/asn1/test/asn1_SUITE_data/ValueTest.asn
+++ b/lib/asn1/test/asn1_SUITE_data/ValueTest.asn
@@ -1,4 +1,4 @@
-ValueTest DEFINITIONS ::=
+ValueTest DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
@@ -41,7 +41,6 @@ objectdescriptor ObjectDescriptor ::= "ObjectDescriptor"
graphicstring GraphicString ::= "GraphicString"
generalstring GeneralString ::= "GeneralString"
bmpstring1 BMPString ::= "BMPString"
---bmpstring2 BMPString ::= [{0,0,0,66},{0,0,0,77},{0,0,0,80},{0,0,0,115},{0,0,0,116},{0,0,0,114},{0,0,0,105},{0,0,0,110},{0,0,0,103}]
latinCapitalLetterA UniversalString ::= {0,0,0,65}
greekCapitalLetterSigma UniversalString ::= {0,0,3,145}
my-universalstring UniversalString ::= {"This is a capital A: ",
@@ -61,4 +60,23 @@ someInteger INTEGER ::= 42
integerSeq1 IntegerSeq ::= { a otherInteger }
otherInteger INTEGER ::= someInteger
+--
+-- Values from objects.
+--
+int-from-object-1 INTEGER ::= int-holder-2.&obj.&id
+int-from-object-2 INTEGER ::= int-holder-2.&id
+
+INT-HOLDER ::= CLASS {
+ &id INTEGER UNIQUE,
+ &obj INT-HOLDER OPTIONAL
+} WITH SYNTAX {
+ ID &id
+ [OBJ &obj]
+}
+
+int-holder-1 INT-HOLDER ::= { ID 2 }
+int-holder-2 INT-HOLDER ::= { ID 4 OBJ int-holder-1 }
+
+II ::= INTEGER (int-from-object-1..int-from-object-2)
+
END
diff --git a/lib/asn1/test/error_SUITE.erl b/lib/asn1/test/error_SUITE.erl
index 36ec7a8203..630daf75c6 100644
--- a/lib/asn1/test/error_SUITE.erl
+++ b/lib/asn1/test/error_SUITE.erl
@@ -20,9 +20,9 @@
-module(error_SUITE).
-export([suite/0,all/0,groups/0,
already_defined/1,bitstrings/1,
- classes/1,enumerated/1,
+ classes/1,constraints/1,enumerated/1,
imports/1,instance_of/1,integers/1,objects/1,
- parameterization/1,values/1]).
+ object_field_extraction/1,parameterization/1,values/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -36,11 +36,13 @@ groups() ->
[already_defined,
bitstrings,
classes,
+ constraints,
enumerated,
imports,
instance_of,
integers,
objects,
+ object_field_extraction,
parameterization,
values]}].
@@ -108,6 +110,29 @@ classes(Config) ->
]} = run(P, Config),
ok.
+constraints(Config) ->
+ M = 'Constraints',
+ P = {M,
+ <<"Constraints DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+ " II-1 ::= INTEGER (holder-1.&obj)\n"
+ " II-2 ::= INTEGER ('1234'H<..20)\n"
+ " II-3 ::= INTEGER (1..<\"abc\")\n"
+
+ " HOLDER ::= CLASS {\n"
+ " &obj HOLDER OPTIONAL\n"
+ " }\n"
+
+ " holder-1 HOLDER ::= { &obj holder-2 }\n"
+ " holder-2 HOLDER ::= { }\n"
+ "END\n">>},
+ {error,
+ [
+ {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}
+ ]} = run(P, Config),
+ ok.
+
enumerated(Config) ->
M = 'Enumerated',
P = {M,
@@ -235,6 +260,36 @@ objects(Config) ->
} = run(P, Config),
ok.
+object_field_extraction(Config) ->
+ M = 'ObjectFieldExtraction',
+ P = {M,
+ <<"ObjectFieldExtraction DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n"
+
+ " DataObjSet DATA-CLASS ::= {\n"
+ " holder-object-1.&int,\n"
+ " ...\n"
+ " }\n"
+
+ " holder-object-1 HOLDER-CLASS ::= {\n"
+ " &int 42\n"
+ " }\n"
+
+ " HOLDER-CLASS ::= CLASS {\n"
+ " &int INTEGER\n"
+ " }\n"
+
+ " DATA-CLASS ::= CLASS {\n"
+ " &id INTEGER\n"
+ " }\n"
+
+ "END\n">>},
+ {error,
+ [
+ {structured_error,{M,2},asn1ct_check,illegal_object}
+ ]
+ } = run(P, Config),
+ ok.
+
parameterization(Config) ->
M = 'Parameterization',
P = {M,
@@ -260,6 +315,16 @@ values(Config) ->
" int1 INTEGER ::= \"string\"\n"
" int2 INTEGER ::= os4\n"
" int3 INTEGER ::= not-defined\n"
+ " int4 INTEGER ::= holder-1.&str\n"
+ " int5 INTEGER ::= holder-2.&obj\n"
+
+ " HOLDER ::= CLASS {\n"
+ " &str IA5String,\n"
+ " &obj HOLDER OPTIONAL\n"
+ " }\n"
+
+ " holder-1 HOLDER ::= { &str \"xyz\" }\n"
+ " holder-2 HOLDER ::= { &str \"xyz\", &obj holder-1 }\n"
"END\n">>},
{error,
[
@@ -274,6 +339,10 @@ values(Config) ->
{structured_error,{M,7},asn1ct_check,
illegal_integer_value},
{structured_error,{M,8},asn1ct_check,
+ illegal_integer_value},
+ {structured_error,{M,9},asn1ct_check,
+ illegal_integer_value},
+ {structured_error,{M,10},asn1ct_check,
illegal_integer_value}
]
} = run(P, Config),
diff --git a/lib/asn1/test/testConstraints.erl b/lib/asn1/test/testConstraints.erl
index 3ccf883bd6..aab4f1d4c6 100644
--- a/lib/asn1/test/testConstraints.erl
+++ b/lib/asn1/test/testConstraints.erl
@@ -231,6 +231,15 @@ int_constraints(Rules) ->
seq_roundtrip(Rules, 'SeqOverlapping', 'SeqNonOverlapping', 19000),
seq_roundtrip(Rules, 'SeqOverlapping', 'SeqNonOverlapping', 26900),
+ %%==========================================================
+ %% Constraints from object fields.
+ %%==========================================================
+ range_error(Rules, 'IntObjectConstr', 1),
+ roundtrip('IntObjectConstr', 2),
+ roundtrip('IntObjectConstr', 3),
+ roundtrip('IntObjectConstr', 4),
+ range_error(Rules, 'IntObjectConstr', 5),
+
ok.
%% PER: Ensure that if the lower bound is Lb, Lb+16#80 is encoded
diff --git a/lib/asn1/test/testInfObjExtract.erl b/lib/asn1/test/testInfObjExtract.erl
new file mode 100644
index 0000000000..4e148824fe
--- /dev/null
+++ b/lib/asn1/test/testInfObjExtract.erl
@@ -0,0 +1,47 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(testInfObjExtract).
+
+-export([main/0]).
+
+main() ->
+ roundtrip('DataSeq-1', {'DataSeq-1',1,true}),
+ roundtrip('DataSeq-1', {'DataSeq-1',2,<<"abc">>}),
+ roundtrip('DataSeq-1', {'DataSeq-1',3,<<42:5>>}),
+ roundtrip_error('DataSeq-1', {'DataSeq-1',4,42}),
+
+ roundtrip('DataSeq-2', {'DataSeq-2',1,true}),
+ roundtrip_error('DataSeq-2', {'DataSeq',2,<<"abc">>}),
+ roundtrip_error('DataSeq-2', {'DataSeq',3,<<42:5>>}),
+ roundtrip_error('DataSeq-2', {'DataSeq',999,42}),
+ ok.
+
+roundtrip(T, V) ->
+ asn1_test_lib:roundtrip('InfObjExtract', T, V).
+
+roundtrip_error(T, V) ->
+ try asn1_test_lib:roundtrip('InfObjExtract', T, V) of
+ ok ->
+ test_server:fail()
+ catch
+ _:_ ->
+ ok
+ end.
diff --git a/lib/asn1/test/testValueTest.erl b/lib/asn1/test/testValueTest.erl
index fdd8b006e2..d9cc3de5eb 100644
--- a/lib/asn1/test/testValueTest.erl
+++ b/lib/asn1/test/testValueTest.erl
@@ -63,4 +63,24 @@ main() ->
42 = M:otherInteger(),
{'IntegerSeq',42} = M:integerSeq1(),
+ %% Value from object
+ 2 = M:'int-from-object-1'(),
+ 4 = M:'int-from-object-2'(),
+ roundtrip_error('II', 1),
+ roundtrip('II', 2),
+ roundtrip('II', 3),
+ roundtrip('II', 4),
+ roundtrip_error('II', 5),
+
ok.
+
+roundtrip(T, V) ->
+ asn1_test_lib:roundtrip('ValueTest', T, V).
+
+roundtrip_error(T, V) ->
+ try asn1_test_lib:roundtrip('ValueTest', T, V) of
+ ok ->
+ test_server:fail()
+ catch _:_ ->
+ ok
+ end.