aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2014-01-20 15:31:21 +0100
committerBjörn Gustavsson <[email protected]>2014-01-24 16:24:55 +0100
commit4bda9201055daf3abbdb5ef48bbdd0efacfd1fbc (patch)
tree1696fdc27de1f5d13ec15826919edaef372f3819 /lib/asn1/src
parentbd9e8cf011ee6c1391c134287f0fe877e51c54b8 (diff)
downloadotp-4bda9201055daf3abbdb5ef48bbdd0efacfd1fbc.tar.gz
otp-4bda9201055daf3abbdb5ef48bbdd0efacfd1fbc.tar.bz2
otp-4bda9201055daf3abbdb5ef48bbdd0efacfd1fbc.zip
Fix BIT STRING
Diffstat (limited to 'lib/asn1/src')
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl46
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl28
-rw-r--r--lib/asn1/src/asn1ct_gen_per.erl9
-rw-r--r--lib/asn1/src/asn1ct_imm.erl35
-rw-r--r--lib/asn1/src/asn1rtt_ber.erl51
-rw-r--r--lib/asn1/src/asn1rtt_per_common.erl24
6 files changed, 167 insertions, 26 deletions
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index c224f4c9fa..f2509d1324 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -906,26 +906,36 @@ def_values(#type{def=#'Externaltypereference'{module=Mod,type=Type}}, Def) ->
#typedef{typespec=T} = asn1_db:dbget(Mod, Type),
def_values(T, Def);
def_values(#type{def={'BIT STRING',[]}}, Bs) when is_bitstring(Bs) ->
- ListBs = [B || <<B:1>> <= Bs],
- IntBs = lists:foldl(fun(B, A) ->
- (A bsl 1) bor B
- end, 0, lists:reverse(ListBs)),
- Sz = bit_size(Bs),
- Compact = case 8 - Sz rem 8 of
- 8 ->
- {0,Bs};
- Unused ->
- {Unused,<<Bs:Sz/bits,0:Unused>>}
- end,
- [asn1_DEFAULT,Bs,Compact,ListBs,IntBs];
+ case asn1ct:use_legacy_types() of
+ false ->
+ [asn1_DEFAULT,Bs];
+ true ->
+ ListBs = [B || <<B:1>> <= Bs],
+ IntBs = lists:foldl(fun(B, A) ->
+ (A bsl 1) bor B
+ end, 0, lists:reverse(ListBs)),
+ Sz = bit_size(Bs),
+ Compact = case 8 - Sz rem 8 of
+ 8 ->
+ {0,Bs};
+ Unused ->
+ {Unused,<<Bs:Sz/bits,0:Unused>>}
+ end,
+ [asn1_DEFAULT,Bs,Compact,ListBs,IntBs]
+ end;
def_values(#type{def={'BIT STRING',[_|_]=Ns}}, List) when is_list(List) ->
Bs = asn1ct_gen:named_bitstring_value(List, Ns),
- ListBs = [B || <<B:1>> <= Bs],
- IntBs = lists:foldl(fun(B, A) ->
- (A bsl 1) bor B
- end, 0, lists:reverse(ListBs)),
- Args = [List,Bs,ListBs,IntBs],
- {call,per_common,is_default_bitstring,Args};
+ As = case asn1ct:use_legacy_types() of
+ false ->
+ [List,Bs];
+ true ->
+ ListBs = [B || <<B:1>> <= Bs],
+ IntBs = lists:foldl(fun(B, A) ->
+ (A bsl 1) bor B
+ end, 0, lists:reverse(ListBs)),
+ [List,Bs,ListBs,IntBs]
+ end,
+ {call,per_common,is_default_bitstring,As};
def_values(#type{def={'INTEGER',Ns}}, Def) ->
[asn1_DEFAULT,Def|case lists:keyfind(Def, 2, Ns) of
false -> [];
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
index de81259fcb..84cda4491b 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -206,10 +206,32 @@ gen_encode_prim(_Erules, #type{}=D, DoTag, Value) ->
{call,ber,encode_tags,
[DoTag,{curr,realval},{curr,realsize}]},nl,
"end"]);
+ {'BIT STRING',[]} ->
+ case asn1ct:use_legacy_types() of
+ false when BitStringConstraint =:= [] ->
+ call(encode_unnamed_bit_string, [Value,DoTag]);
+ false ->
+ call(encode_unnamed_bit_string,
+ [{asis,BitStringConstraint},Value,DoTag]);
+ true ->
+ call(encode_bit_string,
+ [{asis,BitStringConstraint},Value,
+ {asis,[]},DoTag])
+ end;
{'BIT STRING',NamedNumberList} ->
- call(encode_bit_string,
- [{asis,BitStringConstraint},Value,
- {asis,NamedNumberList},DoTag]);
+ case asn1ct:use_legacy_types() of
+ false when BitStringConstraint =:= [] ->
+ call(encode_named_bit_string,
+ [Value,{asis,NamedNumberList},DoTag]);
+ false ->
+ call(encode_named_bit_string,
+ [{asis,BitStringConstraint},Value,
+ {asis,NamedNumberList},DoTag]);
+ true ->
+ call(encode_bit_string,
+ [{asis,BitStringConstraint},Value,
+ {asis,NamedNumberList},DoTag])
+ end;
'NULL' ->
call(encode_null, [Value,DoTag]);
'OBJECT IDENTIFIER' ->
diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index 7ba649c874..1885f782bd 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -132,7 +132,14 @@ gen_encode_prim_imm(Val, #type{def=Type0,constraint=Constraint}, Aligned) ->
ToBinary = {real_common,encode_real},
asn1ct_imm:per_enc_restricted_string(Val, ToBinary, Aligned);
{'BIT STRING',NNL} ->
- asn1ct_imm:per_enc_bit_string(Val, NNL, Constraint, Aligned);
+ case asn1ct:use_legacy_types() of
+ false ->
+ asn1ct_imm:per_enc_bit_string(Val, NNL,
+ Constraint, Aligned);
+ true ->
+ asn1ct_imm:per_enc_legacy_bit_string(Val, NNL,
+ Constraint, Aligned)
+ end;
'NULL' ->
asn1ct_imm:per_enc_null(Val, Aligned);
'OBJECT IDENTIFIER' ->
diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl
index c14f0b889f..9da8658f19 100644
--- a/lib/asn1/src/asn1ct_imm.erl
+++ b/lib/asn1/src/asn1ct_imm.erl
@@ -26,7 +26,8 @@
per_dec_octet_string/2,per_dec_open_type/1,per_dec_real/1,
per_dec_restricted_string/1]).
-export([per_dec_constrained/3,per_dec_normally_small_number/1]).
--export([per_enc_bit_string/4,per_enc_boolean/2,
+-export([per_enc_bit_string/4,per_enc_legacy_bit_string/4,
+ per_enc_boolean/2,
per_enc_choice/3,per_enc_enumerated/3,
per_enc_integer/3,per_enc_integer/4,
per_enc_null/2,
@@ -157,7 +158,35 @@ per_dec_restricted_string(Aligned) ->
%%% Encoding.
%%%
-per_enc_bit_string(Val0, [], Constraint0, Aligned) ->
+per_enc_bit_string(Val, [], Constraint0, Aligned) ->
+ {B,[[],Bits]} = mk_vars([], [bits]),
+ Constraint = effective_constraint(bitstring, Constraint0),
+ B ++ [{call,erlang,bit_size,[Val],Bits}|
+ per_enc_length(Val, 1, Bits, Constraint, Aligned, 'BIT STRING')];
+per_enc_bit_string(Val0, NNL0, Constraint0, Aligned) ->
+ {B,[Val,Bs,Bits,Positions]} = mk_vars(Val0, [bs,bits,positions]),
+ NNL = lists:keysort(2, NNL0),
+ Constraint = effective_constraint(bitstring, Constraint0),
+ ExtraArgs = case constr_min_size(Constraint) of
+ no -> [];
+ Lb -> [Lb]
+ end,
+ ToBs = case ExtraArgs of
+ [] ->
+ {call,per_common,bs_drop_trailing_zeroes,[Val]};
+ [Lower] ->
+ {call,per_common,adjust_trailing_zeroes,[Val,Lower]}
+ end,
+ B ++ [{'try',
+ [bit_string_name2pos_fun(NNL, Val)],
+ {Positions,
+ [{call,per_common,bitstring_from_positions,
+ [Positions|ExtraArgs]}]},
+ [ToBs],Bs},
+ {call,erlang,bit_size,[Bs],Bits}|
+ per_enc_length(Bs, 1, Bits, Constraint, Aligned, 'BIT STRING')].
+
+per_enc_legacy_bit_string(Val0, [], Constraint0, Aligned) ->
{B,[Val,Bs,Bits]} = mk_vars(Val0, [bs,bits]),
Constraint = effective_constraint(bitstring, Constraint0),
ExtraArgs = case constr_min_size(Constraint) of
@@ -167,7 +196,7 @@ per_enc_bit_string(Val0, [], Constraint0, Aligned) ->
B ++ [{call,per_common,to_bitstring,[Val|ExtraArgs],Bs},
{call,erlang,bit_size,[Bs],Bits}|
per_enc_length(Bs, 1, Bits, Constraint, Aligned, 'BIT STRING')];
-per_enc_bit_string(Val0, NNL0, Constraint0, Aligned) ->
+per_enc_legacy_bit_string(Val0, NNL0, Constraint0, Aligned) ->
{B,[Val,Bs,Bits,Positions]} = mk_vars(Val0, [bs,bits,positions]),
NNL = lists:keysort(2, NNL0),
Constraint = effective_constraint(bitstring, Constraint0),
diff --git a/lib/asn1/src/asn1rtt_ber.erl b/lib/asn1/src/asn1rtt_ber.erl
index 583ff790b7..a4aa347aea 100644
--- a/lib/asn1/src/asn1rtt_ber.erl
+++ b/lib/asn1/src/asn1rtt_ber.erl
@@ -29,6 +29,8 @@
decode_integer/2,decode_integer/3,
decode_named_integer/3,decode_named_integer/4,
encode_enumerated/2,decode_enumerated/3,
+ encode_unnamed_bit_string/2,encode_unnamed_bit_string/3,
+ encode_named_bit_string/3,encode_named_bit_string/4,
encode_bit_string/4,
decode_named_bit_string/3,
decode_compact_bit_string/3,
@@ -780,6 +782,55 @@ decode_enumerated1(Val, NamedNumberList) ->
{asn1_enum,Val}
end.
+%%============================================================================
+%% Bitstring value, ITU_T X.690 Chapter 8.6
+%%
+%% encode bitstring value
+%%============================================================================
+
+encode_unnamed_bit_string(Bits, TagIn) ->
+ Unused = (8 - (bit_size(Bits) band 7)) band 7,
+ Bin = <<Unused,Bits/bitstring,0:Unused>>,
+ encode_tags(TagIn, Bin, byte_size(Bin)).
+
+encode_unnamed_bit_string(C, Bits, TagIn) ->
+ NumBits = bit_size(Bits),
+ Unused = (8 - (NumBits band 7)) band 7,
+ Bin = <<Unused,Bits/bitstring,0:Unused>>,
+ case C of
+ {_Min,Max} ->
+ if
+ NumBits > Max ->
+ exit({error,{asn1,
+ {bitstring_length,
+ {{was,NumBits},{maximum,Max}}}}});
+ true ->
+ ok
+ end;
+ Size ->
+ if NumBits =< Size ->
+ ok;
+ true ->
+ exit({error,{asn1,
+ {bitstring_length,
+ {{was,NumBits},{should_be,Size}}}}})
+ end
+ end,
+ encode_tags(TagIn, Bin, byte_size(Bin)).
+
+encode_named_bit_string([H|_]=Bits, NamedBitList, TagIn) when is_atom(H) ->
+ encode_bit_string_named([], Bits, NamedBitList, TagIn);
+encode_named_bit_string([{bit,_}|_]=Bits, NamedBitList, TagIn) ->
+ encode_bit_string_named([], Bits, NamedBitList, TagIn);
+encode_named_bit_string(Bits, _NamedBitList, TagIn) when is_bitstring(Bits) ->
+ encode_unnamed_bit_string(Bits, TagIn).
+
+encode_named_bit_string(C, [H|_]=Bits, NamedBitList, TagIn) when is_atom(H) ->
+ encode_bit_string_named(C, Bits, NamedBitList, TagIn);
+encode_named_bit_string(C, [{bit,_}|_]=Bits, NamedBitList, TagIn) ->
+ encode_bit_string_named(C, Bits, NamedBitList, TagIn);
+encode_named_bit_string(C, Bits, _NamedBitList, TagIn) when is_bitstring(Bits) ->
+ encode_unnamed_bit_string(C, Bits, TagIn).
%%============================================================================
%% Bitstring value, ITU_T X.690 Chapter 8.6
diff --git a/lib/asn1/src/asn1rtt_per_common.erl b/lib/asn1/src/asn1rtt_per_common.erl
index 3309e6a4ca..e84fa581df 100644
--- a/lib/asn1/src/asn1rtt_per_common.erl
+++ b/lib/asn1/src/asn1rtt_per_common.erl
@@ -37,7 +37,8 @@
bitstring_from_positions/1,bitstring_from_positions/2,
to_bitstring/1,to_bitstring/2,
to_named_bitstring/1,to_named_bitstring/2,
- is_default_bitstring/5,
+ bs_drop_trailing_zeroes/1,adjust_trailing_zeroes/2,
+ is_default_bitstring/3,is_default_bitstring/5,
extension_bitmap/3]).
-define('16K',16384).
@@ -272,6 +273,25 @@ to_named_bitstring(Val, Lb) ->
%% for correctness, not speed.
adjust_trailing_zeroes(to_bitstring(Val), Lb).
+is_default_bitstring(asn1_DEFAULT, _, _) ->
+ true;
+is_default_bitstring(Named, Named, _) ->
+ true;
+is_default_bitstring(Bs, _, Bs) ->
+ true;
+is_default_bitstring(Val, _, Def) when is_bitstring(Val) ->
+ Sz = bit_size(Def),
+ case Val of
+ <<Def:Sz/bitstring,T/bitstring>> ->
+ NumZeroes = bit_size(T),
+ case T of
+ <<0:NumZeroes>> -> true;
+ _ -> false
+ end;
+ _ ->
+ false
+ end.
+
is_default_bitstring(asn1_DEFAULT, _, _, _, _) ->
true;
is_default_bitstring({Unused,Bin}, V0, V1, V2, V3) when is_integer(Unused) ->
@@ -438,6 +458,8 @@ adjust_trailing_zeroes(Bs0, Lb) ->
bs_drop_trailing_zeroes(Bs) ->
bs_drop_trailing_zeroes(Bs, bit_size(Bs)).
+bs_drop_trailing_zeroes(Bs, 0) ->
+ Bs;
bs_drop_trailing_zeroes(Bs0, Sz0) when Sz0 < 8 ->
<<Byte:Sz0>> = Bs0,
Sz = Sz0 - ntz(Byte),