diff options
author | Björn Gustavsson <[email protected]> | 2013-02-28 11:42:47 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2013-05-31 14:52:16 +0200 |
commit | 902b51b8b43fe66fd4488c7fa10c05c3b9da59b4 (patch) | |
tree | 8010da4c1a8791648959839defc53e49c59cd5aa | |
parent | 649114be27c1893bb1624ec02e2948ae4a7332c7 (diff) | |
download | otp-902b51b8b43fe66fd4488c7fa10c05c3b9da59b4.tar.gz otp-902b51b8b43fe66fd4488c7fa10c05c3b9da59b4.tar.bz2 otp-902b51b8b43fe66fd4488c7fa10c05c3b9da59b4.zip |
PER/UPER: Correct encoding of a length outside the root range
Consider a type with a size constraint with an extension marker
such as:
S ::= OCTET STRING (SIZE (0..10, ...))
For a length outside the root range (e.g. 42), the PER/UPER encoder
will encode the length field in the same way as it would the type
INTEGER (0..MAX) (i.e., as semi-constrained whole number), while the
decoder would decode the length in the same way as length field
without any constraint.
Clearly, either the encoder or the decoder is wrong. But which one?
Dubuisson's [1] book (page 442) says that the length should be encoded
as a semi-constrained whole number if the length is outside the root
range.
The X.691 standard document [2] also says (e.g. in 15.11) that length
fields should be a semi-constrained number, but gives a reference
to section gives a reference to section 10.9, "General rules for encoding
a length determinant", and not to to 10.7, "Encoding of a
semi-constrained whole number".
Reading the standard that way should imply that a length outside the
root range should be encoded in the same way as an unconstrained
length, and that the decoder does the right thing.
Further support for that interpretation:
- Larmouth's book [3], page 303.
- The ASN.1 playground. [4]
References:
[1] http://www.oss.com/asn1/resources/books-whitepapers-pubs/dubuisson-asn1-book.PDF
[2] http://www.itu.int/ITU-T/studygroups/com17/languages/X.691-0207.pdf
[3] http://www.oss.com/asn1/resources/books-whitepapers-pubs/larmouth-asn1-book.pdf
[4] http://asn1-playground.oss.com
-rw-r--r-- | lib/asn1/src/asn1rtt_per.erl | 4 | ||||
-rw-r--r-- | lib/asn1/src/asn1rtt_uper.erl | 4 | ||||
-rw-r--r-- | lib/asn1/test/testConstraints.erl | 4 |
3 files changed, 8 insertions, 4 deletions
diff --git a/lib/asn1/src/asn1rtt_per.erl b/lib/asn1/src/asn1rtt_per.erl index b30a7aebd2..b8971b7c33 100644 --- a/lib/asn1/src/asn1rtt_per.erl +++ b/lib/asn1/src/asn1rtt_per.erl @@ -359,8 +359,8 @@ encode_length({{Lb,Ub}=Vr,Ext}, Len) when Ub =< 65535 ,Lb >= 0,Len=<Ub, is_list(Ext) -> %% constrained extensible [0|encode_constrained_number(Vr,Len)]; -encode_length({{Lb,_},Ext},Len) when is_list(Ext) -> - [1|encode_semi_constrained_number(Lb, Len)]; +encode_length({{_,_},Ext},Len) when is_list(Ext) -> + [1|encode_length(Len)]; encode_length(SingleValue, _Len) when is_integer(SingleValue) -> []. diff --git a/lib/asn1/src/asn1rtt_uper.erl b/lib/asn1/src/asn1rtt_uper.erl index e55535860f..3f362d227e 100644 --- a/lib/asn1/src/asn1rtt_uper.erl +++ b/lib/asn1/src/asn1rtt_uper.erl @@ -358,8 +358,8 @@ encode_length({{Lb,Ub}=Vr,Ext},Len) when Ub =< 65535, Lb >= 0, Len =< Ub, is_list(Ext) -> %% constrained extensible [<<0:1>>,encode_constrained_number(Vr,Len)]; -encode_length({{Lb,_Ub},Ext}, Len) when is_list(Ext) -> - [<<1:1>>,encode_semi_constrained_number(Lb, Len)]; +encode_length({{_Lb,_Ub},Ext}, Len) when is_list(Ext) -> + [<<1:1>>,encode_length(Len)]; encode_length(SingleValue, _Len) when is_integer(SingleValue) -> []. diff --git a/lib/asn1/test/testConstraints.erl b/lib/asn1/test/testConstraints.erl index ef6c1b3486..d6db1c2b91 100644 --- a/lib/asn1/test/testConstraints.erl +++ b/lib/asn1/test/testConstraints.erl @@ -128,7 +128,11 @@ int_constraints(Rules) -> %%========================================================== roundtrip('T', "IA"), + roundtrip('T', "IAB"), + roundtrip('T', "IABC"), roundtrip('T2', "IA"), + roundtrip('T2', "IAB"), + roundtrip('T2', "IABC"), %%========================================================== %% More SIZE Constraints |