From c266196c016fc1156c7a18cfeec4920ee4075519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Fri, 23 May 2014 12:10:46 +0200 Subject: Fix problem with object identifiers in external modules When parsing ASN.1, certain constructs can only be understood in the full context of the entire ASN.1 module. For instance, the value following ID in this simplified excerpt from MTSAbstractService88: administration-88 PORT ::= { ID {id-pt-administration 88} } the value following "ID" can be interpreted either as value for: SEQUENCE { id-pt-administration INTEGER } or as an OBJECT IDENTIFIER. Our ASN.1 parser assumes that a SEQUENCE is meant, and if that later turns out to be wrong, the SEQUENCE value is rewritten to an OBJECT IDENTIFIER. The problem is that at the time of the rewrite, we no longer know in which ASN.1 module id-pt-administration was defined in, and we have to use the module name in the state{} record. Unfortunately, the module name in the state{} record may not always be correct. While there are attempts in the code to keep the module name up-to-date when checking imported types, it is not done consistently, and it seems to be a difficult and error-prone task to attempt to make it consistent. A safer and less error-prone approach is to make sure that we don't lose the module name while parsing. To make it clear what we are doing, we will introduce a new #seqtag{} record that are used for tags in SEQUENCE values. The name is based on its primary use. The record also contains the module in case it happens to be an OBJECT IDENTIFIER. --- lib/asn1/src/asn1ct_parser2.erl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/asn1/src/asn1ct_parser2.erl') diff --git a/lib/asn1/src/asn1ct_parser2.erl b/lib/asn1/src/asn1ct_parser2.erl index 444c8969f1..f9c4387ca0 100644 --- a/lib/asn1/src/asn1ct_parser2.erl +++ b/lib/asn1/src/asn1ct_parser2.erl @@ -2866,13 +2866,14 @@ parse_SequenceValue(Tokens) -> throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module), [got,get_token(hd(Tokens)),expected,'{']}}). -parse_SequenceValue([{identifier,_,IdName}|Rest],Acc) -> +parse_SequenceValue([{identifier,Pos,IdName}|Rest],Acc) -> {Value,Rest2} = parse_Value(Rest), + SeqTag = #seqtag{pos=Pos,module=get(asn1_module),val=IdName}, case Rest2 of [{',',_}|Rest3] -> - parse_SequenceValue(Rest3,[{IdName,Value}|Acc]); + parse_SequenceValue(Rest3, [{SeqTag,Value}|Acc]); [{'}',_}|Rest3] -> - {lists:reverse([{IdName,Value}|Acc]),Rest3}; + {lists:reverse(Acc, [{SeqTag,Value}]),Rest3}; _ -> throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module), [got,get_token(hd(Rest2)),expected,'}']}}) -- cgit v1.2.3