diff options
author | Björn Gustavsson <[email protected]> | 2014-12-01 13:35:04 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-01-12 11:40:28 +0100 |
commit | 1c7802251322ea82ab7a7c5098034a88db69e787 (patch) | |
tree | 98bbab7b16ad68b1f82bb3a1a8db70592674a109 /lib/asn1 | |
parent | 303fff739a00200a2a2adf3104e80a9e48012563 (diff) | |
download | otp-1c7802251322ea82ab7a7c5098034a88db69e787.tar.gz otp-1c7802251322ea82ab7a7c5098034a88db69e787.tar.bz2 otp-1c7802251322ea82ab7a7c5098034a88db69e787.zip |
BER: Fix ENUMERATED with negative values
The ASN.1 compiler would go into an infinite loop if a value
in an ENUMERATED was negative.
Diffstat (limited to 'lib/asn1')
-rw-r--r-- | lib/asn1/src/asn1ct_gen_ber_bin_v2.erl | 24 | ||||
-rw-r--r-- | lib/asn1/test/asn1_SUITE_data/Prim.asn1 | 2 | ||||
-rw-r--r-- | lib/asn1/test/testPrim.erl | 5 |
3 files changed, 26 insertions, 5 deletions
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl index 4dedd6305c..37413298a7 100644 --- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl +++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl @@ -278,8 +278,7 @@ emit_enc_enumerated_cases(L, Tags) -> emit_enc_enumerated_cases(L, Tags, noext). emit_enc_enumerated_cases([{EnumName,EnumVal}|T], Tags, Ext) -> - Bytes = encode_pos_integer(EnumVal, []), - Len = length(Bytes), + {Bytes,Len} = encode_integer(EnumVal), emit([{asis,EnumName}," -> ", {call,ber,encode_tags,[Tags,{asis,Bytes},Len]},";",nl]), emit_enc_enumerated_cases(T, Tags, Ext); @@ -288,10 +287,25 @@ emit_enc_enumerated_cases([], _Tags, _Ext) -> emit([{curr,enumval}," -> exit({error,{asn1, {enumerated_not_in_range,",{curr, enumval},"}}})"]), emit([nl,"end"]). -encode_pos_integer(0, [B|_Acc] = L) when B < 128 -> +encode_integer(Val) -> + Bytes = + if + Val >= 0 -> + encode_integer_pos(Val, []); + true -> + encode_integer_neg(Val, []) + end, + {Bytes,length(Bytes)}. + +encode_integer_pos(0, [B|_Acc]=L) when B < 128 -> + L; +encode_integer_pos(N, Acc) -> + encode_integer_pos((N bsr 8), [N band 16#ff| Acc]). + +encode_integer_neg(-1, [B1|_T]=L) when B1 > 127 -> L; -encode_pos_integer(N, Acc) -> - encode_pos_integer(N bsr 8, [N band 255|Acc]). +encode_integer_neg(N, Acc) -> + encode_integer_neg(N bsr 8, [N band 16#ff|Acc]). %%=============================================================================== %%=============================================================================== diff --git a/lib/asn1/test/asn1_SUITE_data/Prim.asn1 b/lib/asn1/test/asn1_SUITE_data/Prim.asn1 index cc0e61422a..b4c011fd39 100644 --- a/lib/asn1/test/asn1_SUITE_data/Prim.asn1 +++ b/lib/asn1/test/asn1_SUITE_data/Prim.asn1 @@ -24,6 +24,8 @@ BEGIN friday(5),saturday(6),sunday(7)} SingleEnumVal ::= ENUMERATED {true} SingleEnumValExt ::= ENUMERATED {true, ...} + NegEnumVal ::= ENUMERATED {neg(-1), ..., zero(0)} + EnumVal128 ::= ENUMERATED {val(128)} ObjId ::= OBJECT IDENTIFIER diff --git a/lib/asn1/test/testPrim.erl b/lib/asn1/test/testPrim.erl index e07379e634..d7893a2d58 100644 --- a/lib/asn1/test/testPrim.erl +++ b/lib/asn1/test/testPrim.erl @@ -98,6 +98,11 @@ enum(Rules) -> ber -> ok end, + + roundtrip('NegEnumVal', neg), + roundtrip('NegEnumVal', zero), + roundtrip('EnumVal128', val), + ok. |