aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-12-04 12:51:11 +0100
committerBjörn Gustavsson <[email protected]>2012-12-06 14:22:37 +0100
commit9f83121db1cea3f9b3a8f87435b1767285556ab6 (patch)
tree84e1e2d7165c4e0df1c3ef99b58584876bf0112d
parente55031640646c7439aff619dcf78bfa76e725109 (diff)
downloadotp-9f83121db1cea3f9b3a8f87435b1767285556ab6.tar.gz
otp-9f83121db1cea3f9b3a8f87435b1767285556ab6.tar.bz2
otp-9f83121db1cea3f9b3a8f87435b1767285556ab6.zip
Implement encoding of fragmented OCTET STRINGs
Decoding of a fragmented OCTET STRING with the size constrained to a single value is implemented, but encoding is not implemented, and decoding is not tested in any test case. There is no urgent need to support encoding of fragmented OCTET STRINGs, but not being able to encode such values complicates testing of decoding. For example, eif we add the following type to PrimStrings.asn1 in the test suite: FixedOs65536 ::= OCTET STRING (SIZE (65536)) then asn1ct:test('PrimStrings') will fail because this value cannot be encoded.
-rw-r--r--lib/asn1/src/asn1rt_per_bin_rt2ct.erl48
-rw-r--r--lib/asn1/src/asn1rt_uper_bin.erl51
2 files changed, 86 insertions, 13 deletions
diff --git a/lib/asn1/src/asn1rt_per_bin_rt2ct.erl b/lib/asn1/src/asn1rt_per_bin_rt2ct.erl
index dfe03f9c5d..a7536ee88b 100644
--- a/lib/asn1/src/asn1rt_per_bin_rt2ct.erl
+++ b/lib/asn1/src/asn1rt_per_bin_rt2ct.erl
@@ -1312,19 +1312,55 @@ encode_octet_string(SZ={_,_},false,Val) ->
% [encode_length(SZ,length(Val)),align,
% {octets,Val}];
Len = length(Val),
- [encode_length(SZ,Len),2,
- octets_to_complete(Len,Val)];
+ try
+ [encode_length(SZ,Len),2,
+ octets_to_complete(Len,Val)]
+ catch
+ exit:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end;
encode_octet_string(SZ,false,Val) when is_list(SZ) ->
Len = length(Val),
- [encode_length({hd(SZ),lists:max(SZ)},Len),2,
- octets_to_complete(Len,Val)];
+ try
+ [encode_length({hd(SZ),lists:max(SZ)},Len),2,
+ octets_to_complete(Len,Val)]
+ catch
+ exit:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end;
+encode_octet_string(Sv,false,Val) when is_integer(Sv) ->
+ encode_fragmented_octet_string(Val);
encode_octet_string(no,false,Val) ->
Len = length(Val),
- [encode_length(undefined,Len),2,
- octets_to_complete(Len,Val)];
+ try
+ [encode_length(undefined,Len),2,
+ octets_to_complete(Len,Val)]
+ catch
+ exit:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end;
encode_octet_string(C,_,_) ->
exit({error,{not_implemented,C}}).
+encode_fragmented_octet_string(Val) ->
+ Bin = iolist_to_binary(Val),
+ efos_1(Bin).
+
+efos_1(<<B1:16#C000/binary,B2:16#4000/binary,T/binary>>) ->
+ [20,1,<<3:2,4:6>>,
+ octets_to_complete(16#C000, B1),
+ octets_to_complete(16#4000, B2)|efos_1(T)];
+efos_1(<<B:16#C000/binary,T/binary>>) ->
+ [20,1,<<3:2,3:6>>,octets_to_complete(16#C000, B)|efos_1(T)];
+efos_1(<<B:16#8000/binary,T/binary>>) ->
+ [20,1,<<3:2,2:6>>,octets_to_complete(16#8000, B)|efos_1(T)];
+efos_1(<<B:16#4000/binary,T/binary>>) ->
+ [20,1,<<3:2,1:6>>,octets_to_complete(16#4000, B)|efos_1(T)];
+efos_1(<<>>) ->
+ [20,1,0];
+efos_1(<<B/bitstring>>) ->
+ Len = byte_size(B),
+ [encode_length(undefined, Len),octets_to_complete(Len, B)].
decode_octet_string(Bytes,Range) ->
decode_octet_string(Bytes,Range,false).
diff --git a/lib/asn1/src/asn1rt_uper_bin.erl b/lib/asn1/src/asn1rt_uper_bin.erl
index 6f6bfa195e..2cd68c62a0 100644
--- a/lib/asn1/src/asn1rt_uper_bin.erl
+++ b/lib/asn1/src/asn1rt_uper_bin.erl
@@ -582,7 +582,7 @@ encode_length(undefined,Len) -> % un-constrained
Len < 16384 ->
<<2:2,Len:14>>;
true -> % should be able to endode length >= 16384
- exit({error,{asn1,{encode_length,{nyi,above_16k}}}})
+ error({error,{asn1,{encode_length,{nyi,above_16k}}}})
end;
encode_length({0,'MAX'},Len) ->
@@ -1052,16 +1052,53 @@ encode_octet_string(C,Val) ->
list_to_binary(Val);
2 ->
list_to_binary(Val);
- Sv when Sv =<65535, Sv == length(Val) -> % fixed length
- list_to_binary(Val);
- VR = {_,_} ->
- [encode_length(VR,length(Val)),list_to_binary(Val)];
+ {_,_}=VR ->
+ try
+ [encode_length(VR, length(Val)),list_to_binary(Val)]
+ catch
+ error:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end;
+ Sv when is_integer(Sv), Sv =:= length(Val) -> % fixed length
+ if
+ Sv =< 65535 ->
+ list_to_binary(Val);
+ true ->
+ encode_fragmented_octet_string(Val)
+ end;
Sv when is_list(Sv) ->
- [encode_length({hd(Sv),lists:max(Sv)},length(Val)),list_to_binary(Val)];
+ try
+ [encode_length({hd(Sv),lists:max(Sv)},
+ length(Val)),list_to_binary(Val)]
+ catch
+ error:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end;
no ->
- [encode_length(undefined,length(Val)),list_to_binary(Val)]
+ try
+ [encode_length(undefined, length(Val)),list_to_binary(Val)]
+ catch
+ error:{error,{asn1,{encode_length,_}}} ->
+ encode_fragmented_octet_string(Val)
+ end
end.
+encode_fragmented_octet_string(Val) ->
+ Bin = list_to_binary(Val),
+ efos_1(Bin).
+
+efos_1(<<B:16#10000/binary,T/binary>>) ->
+ [<<3:2,4:6>>,B|efos_1(T)];
+efos_1(<<B:16#C000/binary,T/binary>>) ->
+ [<<3:2,3:6>>,B|efos_1(T)];
+efos_1(<<B:16#8000/binary,T/binary>>) ->
+ [<<3:2,2:6>>,B|efos_1(T)];
+efos_1(<<B:16#4000/binary,T/binary>>) ->
+ [<<3:2,1:6>>,B|efos_1(T)];
+efos_1(<<B/bitstring>>) ->
+ Len = byte_size(B),
+ [encode_length(undefined, Len),B].
+
decode_octet_string(Bytes,C) ->
decode_octet_string1(Bytes,get_constraint(C,'SizeConstraint')).
decode_octet_string1(<<B1,Bytes/bitstring>>,1) ->