[Re] Patch for asn1 library

View: New views
1 Messages — Rating Filter:   Alert me  

[Re] Patch for asn1 library

by Aude Quintana-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello !

After some other tests with the patch I made previously on asn1 library I had to add some lines in the patch.
(it makes the decoding function to return {error,incomplete} when the buffer passed in argument doesn't contain at least a full message)

So, .diff file joined is the new patch and I hope it is complete now.

Best Regards,
Aude.

[repatch_lib_asn1.diff]

diff -u old/asn1ct_gen.erl new/asn1ct_gen.erl
--- old/asn1ct_gen.erl 2009-08-12 15:44:57.000000000 +0200
+++ new/asn1ct_gen.erl 2009-08-25 12:32:05.000000000 +0200
@@ -950,16 +950,26 @@
     DecAnonymous =
  case {Erules,Return_rest} of
     {ber_bin_v2,false} ->
- io_lib:format("~s~s~s~n",
-      ["element(1,?RT_BER:decode(Data",
-       driver_parameter(),"))"]);
+ emit(["case catch ?RT_BER:decode(Data",
+       driver_parameter(),") of",nl,
+      "  {error,incomplete} ->",nl,
+      "    {error,incomplete};",nl,
+      "  {Data,_Rest} ->",nl]),
+ "Data";
     {ber_bin_v2,true} ->
- emit(["{Data,Rest} = ?RT_BER:decode(Data0",
-      driver_parameter(),"),",nl]),
+ emit(["case catch ?RT_BER:decode(Data0",
+      driver_parameter(),") of",nl,
+      "  {error,incomplete} ->",nl,
+      "    {error,incomplete};",nl,
+      "  {Data,Rest} ->",nl]),
  "Data";
     _ ->
  "Data"
  end,
+    Space = case Erules of
+ ber_bin_v2 -> "    ";
+ _ -> ""
+    end,
     DecWrap = case Erules of
   ber -> "wrap_decode(Data)";
   ber_bin_v2 ->
@@ -968,18 +978,23 @@
   _ -> "Data"
       end,
     
-    emit(["case catch decode_disp(Type,",DecWrap,") of",nl,
-  "  {'EXIT',{error,Reason}} ->",nl,
-  "    {error,Reason};",nl,
-  "  {'EXIT',Reason} ->",nl,
-  "    {error,{asn1,Reason}};",nl]),
+    emit([Space,"case catch decode_disp(Type,",DecWrap,") of",nl,
+  Space,"  {error,incomplete} ->",nl,
+  Space,"    {error,incomplete};",nl,
+  Space,"  {'EXIT',{error,Reason}} ->",nl,
+  Space,"    {error,Reason};",nl,
+  Space,"  {'EXIT',Reason} ->",nl,
+  Space,"    {error,{asn1,Reason}};",nl]),
+    
     case {Erules,Return_rest} of
  {ber_bin_v2,false} ->
-    emit(["  Result ->",nl,
-  "    {ok,Result}",nl]);
+    emit([Space,"  Result ->",nl,
+  Space,"    {ok,Result}",nl,
+  Space,"end",nl]);
  {ber_bin_v2,true} ->
-    emit(["  Result ->",nl,
-  "    {ok,Result,Rest}",nl]);
+    emit([Space,"  Result ->",nl,
+  Space,"    {ok,Result,Rest}",nl,
+  Space,"end",nl]);
  {per,false} ->
     emit(["  {X,_Rest} ->",nl,
   "    {ok,if_binary2list(X)};",nl,
diff -u old/asn1rt_ber_bin.erl new/asn1rt_ber_bin.erl
--- old/asn1rt_ber_bin.erl 2009-08-12 16:02:39.000000000 +0200
+++ new/asn1rt_ber_bin.erl 2009-08-17 19:32:00.000000000 +0200
@@ -150,6 +150,7 @@
 decode_tlv(Bin) ->
     {Tag,Bin1,_Rb1} = decode_tag(Bin),
     {{Len,Bin2},_Rb2} = decode_length(Bin1),
+    check_bin_size(Bin2,Len),
     <<V:Len/binary,Bin3/binary>> = Bin2,
     {{Tag,Len,V},Bin3}.
 
@@ -163,6 +164,7 @@
 split_list(List,indefinite) ->
     {List, indefinite};
 split_list(Bin, Len) when is_binary(Bin) ->
+    check_bin_size(Bin,Len),
     split_binary(Bin,Len);
 split_list(List,Len) ->
     {lists:sublist(List,Len),lists:nthtail(Len,List)}.
@@ -173,6 +175,8 @@
     {RemBytes,2};
 restbytes2(indefinite,RemBytes,ext) ->
     skipvalue(indefinite,RemBytes);
+restbytes2(indefinite,Bin,_) when Bin=:=<<>> orelse Bin=:=<<0>> ->
+    throw({error,incomplete});
 restbytes2(RemBytes,<<>>,_) ->
     {RemBytes,0};
 restbytes2(_RemBytes,Bytes,noext) ->
@@ -208,6 +212,7 @@
  {{0,0,0},0} ->
     skipvalue(indefinite,Bytes3,Rb+2,IndefLevel - 1);
  _ ->
+    check_bin_size(Bytes3,L),
     <<_:L/binary, RestBytes/binary>> = Bytes3,
     skipvalue(indefinite,RestBytes,Rb+R2+R3+L, IndefLevel)
     %%{RestBytes, R2+R3+L}
@@ -218,6 +223,7 @@
 %% _  -> skipvalue(indefinite,Bytes4,Rb+Rb4)
 %%     end;
 skipvalue(L, Bytes, Rb, _) ->
+    check_bin_size(Bytes,L),
 %    <<Skip:L/binary, RestBytes/binary>> = Bytes,
     <<_:L/binary, RestBytes/binary>> = Bytes,
     {RestBytes,Rb+L}.
@@ -325,7 +331,8 @@
 %% interprets the first byte and possible  second, third and fourth byte as
 %% a tag and returns all the bytes comprising the tag, the constructed/primitive bit (6:th bit of first byte) is normalised to 0
 %%
-
+peek_tag(<<>>) ->
+    throw({error,incomplete});
 peek_tag(<<B7_6:2,_:1,31:5,Buffer/binary>>) ->
     Bin = peek_tag(Buffer, <<>>),
     <<B7_6:2,31:6,Bin/binary>>;
@@ -333,6 +340,8 @@
 peek_tag(<<B7_6:2,_:1,B4_0:5,_Buffer/binary>>) ->
     <<B7_6:2,B4_0:6>>.
 
+peek_tag(<<>>,_) ->
+    throw({error,incomplete});
 peek_tag(<<0:1,PartialTag:7,_Buffer/binary>>, TagAck) ->
     <<TagAck/binary,PartialTag>>;
 peek_tag(<<PartialTag,Buffer/binary>>, TagAck) ->
@@ -366,7 +375,9 @@
 
 %% single tag (< 31 tags)
 decode_tag(<<Class:2,Form:1,TagNo:5, Buffer/binary>>) ->
-    {{(Class bsl 6), (Form bsl 5), TagNo}, Buffer, 1}.
+    {{(Class bsl 6), (Form bsl 5), TagNo}, Buffer, 1};
+decode_tag(<<>>) ->
+    throw({error, incomplete}).
 
 %% last partial tag
 decode_tag(<<0:1,PartialTag:7, Buffer/binary>>, TagAck, RemovedBytes) ->
@@ -377,7 +388,9 @@
 decode_tag(<<_:1,PartialTag:7, Buffer/binary>>, TagAck, RemovedBytes) ->
     TagAck1 = (TagAck bsl 7) bor PartialTag,
     %%<<TagAck1:16>> = <<TagAck:1, PartialTag:7,0:8>>,
-    decode_tag(Buffer, TagAck1, RemovedBytes+1).
+    decode_tag(Buffer, TagAck1, RemovedBytes+1);
+decode_tag(<<>>,_TagAck,_RemovedBytes) ->
+    throw({error, incomplete}).
 
 %%------------------------------------------------------------------
 %% check_tags_i is the same as check_tags except that it stops and
@@ -560,6 +573,7 @@
     {_Tag, Len, RemainingBuffer, RemovedBytes} = decode_tag_and_length(Bytes),
     {_RemainingBuffer2, RemovedBytes2} = skipvalue(Len, RemainingBuffer, RemovedBytes),
     N = RemovedBytes2,
+    check_bin_size(Bytes,N),
     <<Val:N/binary, RemainingBytes/binary>> = Bytes,
 %    {Val, RemainingBytes, Len + RemovedBytes}.
     {Val,RemainingBytes,N}.
@@ -579,12 +593,14 @@
     {_RemainingBuffer2, RemovedBytes2} =
  skipvalue(Len, RemainingBuffer),
     N = RemovedBytes2,
+    check_bin_size(Bytes,RemovedBytes+N),
     <<_:RemovedBytes/unit:8,Val:N/binary,RemainingBytes/binary>> = Bytes,
     {Val, RemainingBytes, N + RemovedBytes};
  _ ->
     {_RemainingBuffer2, RemovedBytes2} =
  skipvalue(Len, RemainingBuffer, RemovedBytes),
     N = RemovedBytes2,
+    check_bin_size(Bytes,N),
     <<Val:N/binary, RemainingBytes/binary>> = Bytes,
     {Val, RemainingBytes, N}
     end.
@@ -648,6 +664,8 @@
     {false, Buffer, RemovedBytes + 1};
 decode_boolean2(<<_:8, Buffer/binary>>, RemovedBytes) ->
     {true, Buffer, RemovedBytes + 1};
+decode_boolean2(<<>>,_RemovedBytes) ->
+    throw({error,incomplete});
 decode_boolean2(Buffer, _) ->
     exit({error,{asn1, {decode_boolean, Buffer}}}).
 
@@ -1088,6 +1106,10 @@
 decode_real2(Buffer, _C, 0, _RemBytes) ->
     {0,Buffer};
 decode_real2(Buffer0, _C, Len, RemBytes1) ->
+    case Buffer0 of
+ <<>> -> throw({error,incomplete});
+ _ -> ok
+    end,
     <<First, Buffer2/binary>> = Buffer0,
     if
  First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
@@ -1095,6 +1117,7 @@
 %% First =:= 2#00000000 -> {0, Buffer2};
  First =:= 1 orelse First =:= 2 orelse First =:= 3 ->
     %% charcter string encoding of base 10
+    check_bin_size(Buffer2,Len-1),
     {NRx,Rest} = split_binary(Buffer2,Len-1),
     {binary_to_list(NRx),Rest,Len};
  true ->
@@ -1112,6 +1135,10 @@
     1 -> {3, decode_integer2(2, Buffer2, RemBytes1), RemBytes1+2};
     2 -> {4, decode_integer2(3, Buffer2, RemBytes1), RemBytes1+3};
     3 ->
+ case Buffer2 of
+    <<>> -> throw({error,incomplete});
+    _ -> ok
+ end,
  <<ExpLen1,RestBuffer/binary>> = Buffer2,
  { ExpLen1 + 2,
   decode_integer2(ExpLen1, RestBuffer, RemBytes1),
@@ -1120,6 +1147,7 @@
     %%    io:format("FirstLen: ~w, Exp: ~w, Buffer3: ~w ~n",
 
     Length = Len - FirstLen,
+    check_bin_size(Buffer3,Length),
     <<LongInt:Length/unit:8,RestBuff/binary>> = Buffer3,
     {{Mantissa, Buffer4}, RemBytes3} =
  if Sign =:= 0 ->
@@ -1478,7 +1506,10 @@
     {decode_bitstring_NNL(BitString,NamedNumberList),
      BufferTail,
      RemovedBytes}
-    end.
+    end;
+
+decode_bit_string2(_Len, <<>>,_NamedNumberList,_RemovedBytes,_BinOrOl) ->
+    throw({error,incomplete}).
 
 %%----------------------------------------
 %% Decode the in buffer to bits
@@ -1488,7 +1519,9 @@
 decode_bitstring2(Len, Unused,
   <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Buffer/binary>>) ->
     [B7, B6, B5, B4, B3, B2, B1, B0 |
-     decode_bitstring2(Len - 1, Unused, Buffer)].
+     decode_bitstring2(Len - 1, Unused, Buffer)];
+decode_bitstring2(_Len, _Unused,<<>>) ->
+    throw({error,incomplete}).
 
 %%decode_bitstring2(1, Unused, Buffer) ->
 %%    make_bits_of_int(hd(Buffer), 128, 8-Unused);
@@ -1706,7 +1739,9 @@
 dec_subidentifiers(<<1:1,H:7,T/binary>>,Av,Al,Len) ->
     dec_subidentifiers(T,(Av bsl 7) + H,Al,Len-1);
 dec_subidentifiers(<<H,T/binary>>,Av,Al,Len) ->
-    dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al],Len-1).
+    dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al],Len-1);
+dec_subidentifiers(<<>>,_Av,_Al,_Len) ->
+    throw({error,incomplete}).
 
 %%============================================================================
 %% RELATIVE-OID, ITU_T X.690 Chapter 8.20
@@ -1913,14 +1948,17 @@
     decode_bit_string2(InnerLen,Buffer,NamedNumberList,InnerLen,BinOrOld);
 
  ?N_UniversalString ->
+    check_bin_size(Buffer,InnerLen),
     <<PreBuff:InnerLen/binary,RestBuff/binary>> = Buffer,%%added for binary
     UniString = mk_universal_string(binary_to_list(PreBuff)),
     {UniString,RestBuff,InnerLen};
  ?N_BMPString ->
+    check_bin_size(Buffer,InnerLen),
     <<PreBuff:InnerLen/binary,RestBuff/binary>> = Buffer,%%added for binary
     BMP = mk_BMP_string(binary_to_list(PreBuff)),
     {BMP,RestBuff,InnerLen};
  _ ->
+    check_bin_size(Buffer,InnerLen),
     <<PreBuff:InnerLen/binary,RestBuff/binary>> = Buffer,%%added for binary
     {PreBuff, RestBuff, InnerLen}
     end.
@@ -2007,6 +2045,7 @@
     {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
     {Val01, Buffer02, Rb0+Rb01+Rb02};
  {_,Len} ->
+    check_bin_size(Buffer0,Len),
     <<Result:Len/binary,RestBuff/binary>> = Buffer0,
     {Result,RestBuff,Rb0 + Len}
     end.
@@ -2093,6 +2132,7 @@
     {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
     {Val01, Buffer02, Rb0+Rb01+Rb02};
  {_,Len} ->
+    check_bin_size(Buffer0,Len),
     <<PreBuff:Len/binary,RestBuff/binary>> = Buffer0,
     {binary_to_list(PreBuff), RestBuff, Rb0+Len}
     end.
@@ -2133,6 +2173,7 @@
     {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
     {Val01, Buffer02, Rb0+Rb01+Rb02};
  {_,Len} ->
+    check_bin_size(Buffer0,Len),
     <<PreBuff:Len/binary,RestBuff/binary>> = Buffer0,
     {binary_to_list(PreBuff), RestBuff, Rb0+Len}
     end.
@@ -2184,8 +2225,11 @@
 decode_length(<<0:1,Length:7,T/binary>>) ->
     {{Length,T},1};
 decode_length(<<1:1,LL:7,T/binary>>) ->
+    check_bin_size(T,LL),
     <<Length:LL/unit:8,Rest/binary>> = T,
-    {{Length,Rest}, LL+1}.
+    {{Length,Rest}, LL+1};
+decode_length(<<>>) ->
+    throw({error,incomplete}).
 
 %decode_length([128 | T]) ->
 %    {{indefinite, T},1};
@@ -2431,12 +2475,16 @@
     {EncLen,LenLen}=encode_length(Len),
     {[UniversalTag,EncLen,Bytes],1+LenLen+Len}.
 
+decode_integer2(_Len, <<>>,_RemovedBytes) ->
+    throw({error,incomplete});
 %% decoding postitive integer values.
 decode_integer2(Len,Bin = <<0:1,_:7,_Bs/binary>>,RemovedBytes) ->
+    check_bin_size(Bin,Len),
     <<Int:Len/unit:8,Buffer2/binary>> = Bin,
     {Int,Buffer2,RemovedBytes};
 %% decoding negative integer values.
 decode_integer2(Len,<<1:1,B2:7,Bs/binary>>,RemovedBytes)  ->
+    check_bin_size(Bs,Len-1),
     <<N:Len/unit:8,Buffer2/binary>> = <<B2,Bs/binary>>,
     Int = N - (1 bsl (8 * Len - 1)),
     {Int,Buffer2,RemovedBytes}.
@@ -2495,3 +2543,10 @@
  _ ->
     Tags ++ [LastTag]
     end.
+
+check_bin_size(Binary, ExpectedSize) ->
+    case size(Binary) of
+ Size when Size < ExpectedSize ->
+    throw({error,incomplete});
+ _ -> ok
+    end.
diff -u old/asn1rt_ber_bin_v2.erl new/asn1rt_ber_bin_v2.erl
--- old/asn1rt_ber_bin_v2.erl 2009-08-14 14:16:20.000000000 +0200
+++ new/asn1rt_ber_bin_v2.erl 2009-08-17 19:32:18.000000000 +0200
@@ -505,12 +505,15 @@
 
 %% skip_tag and skip_length_and_value are rutines used both by
 %% decode_partial_incomplete and decode_selective (decode/2).
-
+skip_tag(<<>>) ->
+    throw({error, incomplete});
 skip_tag(<<_:3,31:5,Rest/binary>>)->
     skip_long_tag(Rest);
 skip_tag(<<_:3,_Tag:5,Rest/binary>>) ->
     {ok,Rest}.
 
+skip_long_tag(<<>>) ->
+    throw({error,incomplete});
 skip_long_tag(<<1:1,_:7,Rest/binary>>) ->
     skip_long_tag(Rest);
 skip_long_tag(<<0:1,_:7,Rest/binary>>) ->
@@ -531,6 +534,7 @@
  {indefinite,RestBinary} ->
     skip_indefinite_value(RestBinary);
  {Length,RestBinary} ->
+    check_bin_size(RestBinary,Length),
     <<_:Length/unit:8,Rest/binary>> = RestBinary,
     {ok,Rest}
     end.
@@ -547,6 +551,7 @@
  {indefinite,RestBinary} ->
     get_indefinite_value(RestBinary,[]);
  {Length,RestBinary} ->
+    check_bin_size(RestBinary,Length),
     <<Value:Length/binary,_Rest/binary>> = RestBinary,
     {ok,Value}
     end.
@@ -558,12 +563,16 @@
     {ok,{LenVal,RestBinary2}} = get_length_and_value(RestBinary),
     get_indefinite_value(RestBinary2,[LenVal,Tag|Acc]).
 
+get_tag(<<>>) ->
+    throw({error,incomplete});
 get_tag(<<H:1/binary,Rest/binary>>) ->
     case H of
  <<_:3,31:5>> ->
     get_long_tag(Rest,[H]);
  _ -> {ok,{H,Rest}}
     end.
+get_long_tag(<<>>,_) ->
+    throw({error,incomplete});
 get_long_tag(<<H:1/binary,Rest/binary>>,Acc) ->
     case H of
  <<0:1,_:7>> ->
@@ -572,13 +581,18 @@
     get_long_tag(Rest,[H|Acc])
     end.
 
+get_length_and_value(<<>>) ->
+    throw({error,incomplete});
 get_length_and_value(Bin = <<0:1,Length:7,_T/binary>>) ->
+    check_bin_size(Bin,1+Length),
     <<Len,Val:Length/binary,Rest/binary>> = Bin,
     {ok,{<<Len,Val/binary>>, Rest}};
 get_length_and_value(Bin = <<1:1,0:7,_T/binary>>) ->
     get_indefinite_length_and_value(Bin);
 get_length_and_value(<<1:1,LL:7,T/binary>>) ->
+    check_bin_size(T,LL),
     <<Length:LL/unit:8,Rest/binary>> = T,
+    check_bin_size(Rest,Length),
     <<Value:Length/binary,Rest2/binary>> = Rest,
     {ok,{<<1:1,LL:7,Length:LL/unit:8,Value/binary>>,Rest2}}.
 
@@ -685,6 +699,8 @@
 %%
 %% decode_tag(OctetListBuffer) -> {{Form, (Class bsl 16)+ TagNo}, RestOfBuffer, RemovedBytes}
 %%===============================================================================
+decode_tag_and_length(<<>>) ->
+    throw({error,incomplete});
 
 decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 0:1, Length:7, V:Length/binary, RestBuffer/binary>>) when TagNo < 31 ->
     {Form, (Class bsl 16) + TagNo, V, RestBuffer};
@@ -706,12 +722,21 @@
 decode_tag_and_length(<<Class:2, Form:1, 31:5, Buffer/binary>>) ->
     {TagNo, Buffer1} = decode_tag(Buffer, 0),
     {Length, RestBuffer} = decode_length(Buffer1),
+    check_bin_size(RestBuffer,Length),
     << V:Length/binary, RestBuffer2/binary>> = RestBuffer,
-    {Form, (Class bsl 16) + TagNo, V, RestBuffer2}.
+    {Form, (Class bsl 16) + TagNo, V, RestBuffer2};
 
+decode_tag_and_length(<<_>>) ->
+    throw({error,incomplete});
+decode_tag_and_length(<<_,_:1,L:7,Rest/binary>>) when size(Rest) < L ->
+    throw({error,incomplete});
+decode_tag_and_length(<<_,_:1,LL:7,Length:LL/binary,Rest/binary>>) when size(Rest) < Length ->
+    throw({error,incomplete}).
 
-    
-%% last partial tag
+
+%% last partial tag
+decode_tag(<<>>,_) ->
+    throw({error,incomplete});
 decode_tag(<<0:1,PartialTag:7, Buffer/binary>>, TagAck) ->
     TagNo = (TagAck bsl 7) bor PartialTag,
     %%<<TagNo>> = <<TagAck:1, PartialTag:7>>,
@@ -919,7 +944,9 @@
     range_check_integer(Int,Range),
     Int.
 
-%% decoding postitive integer values.
+%% decoding postitive integer values.
+decode_integer(<<>>) ->
+    throw({error,incomplete});
 decode_integer(Bin = <<0:1,_:7,_/binary>>) ->
     Len = size(Bin),
 %    <<Int:Len/unit:8,Buffer2/binary>> = Bin,
@@ -1087,6 +1114,10 @@
 %%  decode_real2(Buffer, Form, size(Buffer)).
 
 % decode_real2(Buffer, Form, Len) ->
+%     case Buffer of
+%       <<>> -> throw({error,incomplete});
+%       _ -> ok
+%     end,
 %     <<First, Buffer2/binary>> = Buffer,
 %     if
 % First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
@@ -1110,15 +1141,22 @@
 %    {FirstLen,Exp,Buffer3} =
 % case B1_0 of
 %    0 ->
+%                       case Buffer2 of
+%                         <<>> -> throw({error,incomplete});
+%                         _ -> ok
+%                       end,  
 % <<_:1/unit:8,Buffer21/binary>> = Buffer2,
 % {2, decode_integer2(1, Buffer2),Buffer21};
 %    1 ->
+%                       check_bin_size(Buffer2,2),
 % <<_:2/unit:8,Buffer21/binary>> = Buffer2,
 % {3, decode_integer2(2, Buffer2)};
 %    2 ->
+%                       check_bin_size(Buffer2,3),
 % <<_:3/unit:8,Buffer21/binary>> = Buffer2,
 % {4, decode_integer2(3, Buffer2)};
 %    3 ->
+%                       check_bin_size(Buffer2,2),
 % <<ExpLen1,RestBuffer/binary>> = Buffer2,
 % <<_:ExpLen1/unit:8,RestBuffer2/binary>> = RestBuffer,
 % { ExpLen1 + 2,
@@ -1126,6 +1164,7 @@
 %  RestBuffer2}
 % end,
 %    Length = Len - FirstLen,
+%           check_bin_size(Buffer2,Length),
 %    <<LongInt:Length/unit:8,RestBuff/binary>> = Buffer3,
 %    {Mantissa, Buffer4} =
 % if Sign =:= 0 ->
@@ -1424,6 +1463,8 @@
      NamedNumberList,old).
 
 
+decode_bit_string2(<<>>,_,_) ->
+    throw({error,incomplete});
 decode_bit_string2(<<0>>,_NamedNumberList,BinOrOld) ->
     case BinOrOld of
  bin ->
@@ -1453,7 +1494,9 @@
 decode_bitstring2(Len, Unused,
   <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Buffer/binary>>) ->
     [B7, B6, B5, B4, B3, B2, B1, B0 |
-     decode_bitstring2(Len - 1, Unused, Buffer)].
+     decode_bitstring2(Len - 1, Unused, Buffer)];
+decode_bitstring2(_,_Unused,<<>>) ->
+    throw({error,incomplete}).
 
 %%decode_bitstring2(1, Unused, Buffer) ->
 %%    make_bits_of_int(hd(Buffer), 128, 8-Unused);
@@ -1628,7 +1671,7 @@
 dec_subidentifiers(<<1:1,H:7,T/binary>>,Av,Al) ->
     dec_subidentifiers(T,(Av bsl 7) + H,Al);
 dec_subidentifiers(<<H,T/binary>>,Av,Al) ->
-    dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al]).
+    dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al]).
 
 %%============================================================================
 %% RELATIVE-OID, ITU_T X.690 Chapter 8.20
@@ -1965,12 +2008,14 @@
 %% decode_length(OctetList) -> {{indefinite, RestOctetsL}, NoRemovedBytes} |  
 %%                             {{Length, RestOctetsL}, NoRemovedBytes}
 %%===========================================================================
-
+decode_length(<<>>) ->
+    throw({error,incomplete});
 decode_length(<<1:1,0:7,T/binary>>) ->    
     {indefinite, T};
 decode_length(<<0:1,Length:7,T/binary>>) ->
     {Length,T};
 decode_length(<<1:1,LL:7,T/binary>>) ->
+    check_bin_size(T,LL),
     <<Length:LL/unit:8,Rest/binary>> = T,
     {Length,Rest}.
 
@@ -1981,12 +2026,15 @@
 %%-------------------------------------------------------------------------
 
 
-%% decoding postitive integer values.
+%% decoding postitive integer values.
+decode_integer2(_,<<>>) ->
+    throw({error,incomplete});
 decode_integer2(Len,Bin = <<0:1,_:7,_Bs/binary>>) ->
     <<Int:Len/unit:8>> = Bin,
     Int;
 %% decoding negative integer values.
 decode_integer2(Len,<<1:1,B2:7,Bs/binary>>)  ->
+    check_bin_size(Bs,Len-1),
     <<N:Len/unit:8>> = <<B2,Bs/binary>>,
     Int = N - (1 bsl (8 * Len - 1)),
     Int.
@@ -2004,6 +2052,7 @@
 
 collect_parts([{_,L}|Rest],Acc) when is_list(L) ->
     collect_parts(Rest,[collect_parts(L)|Acc]);
+
 collect_parts([{?N_BIT_STRING,<<Unused,Bits/binary>>}|Rest],_Acc) ->
     collect_parts_bit(Rest,[Bits],Unused);
 collect_parts([{_T,V}|Rest],Acc) ->
@@ -2014,10 +2063,16 @@
 collect_parts_bit([{?N_BIT_STRING,<<Unused,Bits/binary>>}|Rest],Acc,Uacc) ->    
     collect_parts_bit(Rest,[Bits|Acc],Unused+Uacc);
 collect_parts_bit([],Acc,Uacc) ->
-    list_to_binary([Uacc|lists:reverse(Acc)]).
-
-
-
+    list_to_binary([Uacc|lists:reverse(Acc)]);
+collect_parts_bit([{?N_BIT_STRING,<<>>}|_Rest],_Acc,_Uacc) ->
+    throw({error,incomplete}).
+
+check_bin_size(Binary,ExpectedSize) ->
+    case size(Binary) of
+ Size when Size < ExpectedSize ->
+    throw({error,incomplete});
+ _ -> ok
+    end.
 
 
 
diff -u old/asn1rt_per_bin.erl new/asn1rt_per_bin.erl
--- old/asn1rt_per_bin.erl 2009-08-13 15:07:50.000000000 +0200
+++ new/asn1rt_per_bin.erl 2009-08-17 19:33:08.000000000 +0200
@@ -241,6 +241,7 @@
     Used = Num rem 8,
     Pad = (8 - Used) rem 8,
 %    Nbytes = Num div 8,
+    check_bit_size(Bin,Num+Pad),
     <<Bits:Num,_:Pad,RestBin/binary>> = Bin,
     {{Pad,<<Bits:Num,0:Pad>>},RestBin};
 getbits_as_binary(Num,Buffer={_Used,_Bin}) -> % Unaligned buffer
@@ -268,23 +269,27 @@
 %% If first byte in buffer is full and at least one byte will be picked,
 %% then pick one byte.
 getbits_as_list(N,{0,Bin},Acc) when N >= 8 ->
+    check_bin_size(Bin,1),
     <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Rest/binary>> = Bin,
     getbits_as_list(N-8,{0,Rest},[B0,B1,B2,B3,B4,B5,B6,B7|Acc]);
 getbits_as_list(N,{Used,Bin},Acc) when N >= 4, Used =< 4 ->
     NewUsed = Used + 4,
     Rem = 8 - NewUsed,
+    check_bit_size(Bin,Used+4+Rem),
     <<_:Used,B3:1,B2:1,B1:1,B0:1,_:Rem, Rest/binary>> = Bin,
     NewRest = case Rem of 0 -> Rest; _ -> Bin end,
     getbits_as_list(N-4,{NewUsed rem 8,NewRest},[B0,B1,B2,B3|Acc]);
 getbits_as_list(N,{Used,Bin},Acc) when N >= 2, Used =< 6  ->
     NewUsed = Used + 2,
     Rem = 8 - NewUsed,
+    check_bit_size(Bin,Used+2+Rem),
     <<_:Used,B1:1,B0:1,_:Rem, Rest/binary>> = Bin,
     NewRest = case Rem of 0 -> Rest; _ -> Bin end,
     getbits_as_list(N-2,{NewUsed rem 8,NewRest},[B0,B1|Acc]);
 getbits_as_list(N,{Used,Bin},Acc) when Used =< 7 ->
     NewUsed = Used + 1,
     Rem = 8 - NewUsed,
+    check_bit_size(Bin,Used+1+Rem),
     <<_:Used,B0:1,_:Rem, Rest/binary>> = Bin,
     NewRest = case Rem of 0 -> Rest; _ -> Bin end,
     getbits_as_list(N-1,{NewUsed rem 8,NewRest},[B0|Acc]).
@@ -296,6 +301,7 @@
     {B,{1,Buffer}};
 getbit({Used,Buffer}) ->
     Unused = (8 - Used) - 1,
+    check_bit_size(Buffer,Used+1+Unused),
     <<_:Used,B:1,_:Unused,_/binary>> = Buffer,
     {B,{Used+1,Buffer}};
 getbit(Buffer) when is_binary(Buffer) ->
@@ -303,6 +309,7 @@
 
 
 getbits({0,Buffer},Num) when (Num rem 8) == 0 ->
+    check_bit_size(Buffer,Num),
     <<Bits:Num,Rest/binary>> = Buffer,
     {Bits,{0,Rest}};
 getbits({Used,Bin},Num) ->
@@ -311,10 +318,12 @@
     Unused = (8-NewUsed) rem 8,
     case Unused of
  0 ->
+    check_bit_size(Bin,Used+Num),
     <<_:Used,Bits:Num,Rest/binary>> = Bin,
     {Bits,{0,Rest}};
  _ ->
     Bytes = NumPlusUsed div 8,
+    check_bit_size(Bin,Used+Num+Unused),
     <<_:Used,Bits:Num,_UBits:Unused,_/binary>> = Bin,
     <<_:Bytes/binary,Rest/binary>> = Bin,
     {Bits,{NewUsed,Rest}}
@@ -345,10 +354,13 @@
 %% First align buffer, then pick the first Num octets.
 %% Returns octets as an integer with bit significance as in buffer.
 getoctets({0,Buffer},Num) ->
+    check_bin_size(Buffer,Num),
     <<Val:Num/integer-unit:8,RestBin/binary>> = Buffer,
     {Val,{0,RestBin}};
 getoctets({U,<<_Padding,Rest/binary>>},Num) when U /= 0 ->
     getoctets({0,Rest},Num);
+getoctets({_U,<<>>},_Num) ->
+    throw({error,incomplete});
 getoctets(Buffer,Num) when is_binary(Buffer) ->
     getoctets({0,Buffer},Num).
 % getoctets(Buffer,Num) ->
@@ -373,9 +385,11 @@
 %% First align buffer, then pick the first Num octets.
 %% Returns octets as a binary
 getoctets_as_bin({0,Bin},Num)->
+    check_bin_size(Bin,Num),
     <<Octets:Num/binary,RestBin/binary>> = Bin,
     {Octets,{0,RestBin}};
 getoctets_as_bin({_U,Bin},Num) ->
+    check_bin_size(Bin,1+Num),
     <<_Padding,Octets:Num/binary,RestBin/binary>> = Bin,
     {Octets,{0,RestBin}};
 getoctets_as_bin(Bin,Num) when is_binary(Bin) ->
@@ -440,7 +454,9 @@
 decode_fragmented_bits({0,Buffer},C) ->
     decode_fragmented_bits(Buffer,C,[]);
 decode_fragmented_bits({_N,<<_,Bs/binary>>},C) ->
-    decode_fragmented_bits(Bs,C,[]).
+    decode_fragmented_bits(Bs,C,[]);
+decode_fragmented_bits({_N,<<>>},_C) ->
+    throw({error,incomplete}).
 
 decode_fragmented_bits(<<3:2,Len:6,Bin/binary>>,C,Acc) ->
     {Value,Bin2} = split_binary(Bin, Len * ?'16K'),
@@ -456,12 +472,14 @@
 decode_fragmented_bits(<<0:1,Len:7,Bin/binary>>,C,Acc) ->
     Result = {BinBits,{Used,_Rest}} =
  case (Len rem 8) of
-    0 ->
+    0 ->
+ check_bit_size(Bin,Len),
  <<Value:Len/binary-unit:1,Bin2/binary>> = Bin,
  {list_to_binary(lists:reverse([Value|Acc])),{0,Bin2}};
     Rem ->
  Bytes = Len div 8,
  U = 8 - Rem,
+ check_bit_size(Bin,Bytes*8+Rem+U),
  <<Value:Bytes/binary-unit:8,Bits1:Rem,Bits2:U,Bin2/binary>> = Bin,
  {list_to_binary(lists:reverse([Bits1 bsl U,Value|Acc])),
  {Rem,<<Bits2,Bin2/binary>>}}
@@ -471,7 +489,9 @@
     Result;
  Int when is_integer(Int) ->
     exit({error,{asn1,{illegal_value,C,BinBits}}})
-    end.
+    end;
+decode_fragmented_bits(<<>>,_C,_Acc) ->
+    throw({error,incomplete}).
 
 
 decode_fragmented_octets({0,Bin},C) ->
@@ -489,6 +509,7 @@
     exit({error,{asn1,{illegal_value,C,Octets}}})
     end;
 decode_fragmented_octets(<<0:1,Len:7,Bin/binary>>,C,Acc) ->
+    check_bin_size(Bin,Len),
     <<Value:Len/binary-unit:8,Bin2/binary>> = Bin,
     BinOctets = list_to_binary(lists:reverse([Value|Acc])),
     case C of
@@ -496,7 +517,9 @@
     {BinOctets,Bin2};
  Int when is_integer(Int) ->
     exit({error,{asn1,{illegal_value,C,BinOctets}}})
-    end.
+    end;
+decode_fragmented_octets(<<>>,_,_) ->
+    throw({error,incomplete}).
 
 
     
@@ -892,8 +915,12 @@
 decode_length(Buffer,undefined)  -> % un-constrained
     {0,Buffer2} = align(Buffer),
     case Buffer2 of
+ Bin when size(Bin) < 1 ->
+    throw({error,incomplete});
  <<0:1,Oct:7,Rest/binary>> ->
     {Oct,{0,Rest}};
+ <<1:1,Rest/bitstring>> when bit_size(Rest) < 15->
+    throw({error, incomplete});
  <<2:2,Val:14,Rest/binary>> ->
     {Val,{0,Rest}};
  <<3:2,_:14,_Rest/binary>> ->
@@ -932,12 +959,17 @@
 decode_length({Used,Bin},{_,_Lb,_Ub}) -> %when Len =< 127 -> % Unconstrained or large Ub NOTE! this case does not cover case when Ub > 65535
     Unused = (8-Used) rem 8,
     case Bin of
+
  <<_:Used,0:1,Val:7,R:Unused,Rest/binary>> ->
     {Val,{Used,<<R,Rest/binary>>}};
+ Bin when bit_size(Bin) < (8+Used+Unused) ->
+    throw({error,incomplete});
  <<_:Used,_:Unused,2:2,Val:14,Rest/binary>> ->
     {Val, {0,Rest}};
  <<_:Used,_:Unused,3:2,_:14,_Rest/binary>> ->
-    exit({error,{asn1,{decode_length,{nyi,length_above_64K}}}})
+    exit({error,{asn1,{decode_length,{nyi,length_above_64K}}}});
+ <<_Used,_:Unused,1:1,_:7,Rest/binary>> when bit_size(Rest) < 8 ->
+    throw({error,incomplete})
     end;
 % decode_length(Buffer,{_,_Lb,Ub}) -> %when Len =< 127 -> % Unconstrained or large Ub
 %     case getbit(Buffer) of
@@ -2280,8 +2312,18 @@
 % complete_bytes2([{V8,B8},{V7,B7},{V6,B6},{V5,B5},{V4,B4},{V3,B3},{V2,B2},{V1,B1}],PadBits) ->
 %     <<V1:B1,V2:B2,V3:B3,V4:B4,V5:B5,V6:B6,V7:B7,V8:B8,0:PadBits>>.
 
-    
-    
+check_bin_size(Binary,ExpectedSize) ->
+    case size(Binary) of
+ Size when Size < ExpectedSize ->
+    throw({error,incomplete});
+ _ -> ok
+    end.
+check_bit_size(BitString,ExpectedSize) ->
+    case bit_size(BitString) of
+ BitSize when BitSize < ExpectedSize ->
+    throw({error,incomplete});
+ _ -> ok
+    end.
     
 
 
diff -u old/asn1rt_per_bin_rt2ct.erl new/asn1rt_per_bin_rt2ct.erl
--- old/asn1rt_per_bin_rt2ct.erl 2009-08-13 19:00:44.000000000 +0200
+++ new/asn1rt_per_bin_rt2ct.erl 2009-08-17 19:33:36.000000000 +0200
@@ -210,20 +210,24 @@
 %% Bin = bitstring(),
 %% Rest = bitstring()
 getbits_as_binary(Num,Bytes) when is_bitstring(Bytes) ->
+    check_bit_size(Bytes,Num),
     <<BS:Num/bitstring,Rest/bitstring>> = Bytes,
     {BS,Rest}.
     
 getbits_as_list(Num,Bytes) when is_bitstring(Bytes) ->
+    check_bit_size(Bytes,Num),
     <<BitStr:Num/bitstring,Rest/bitstring>> = Bytes,
     {[ B || <<B:1>> <= BitStr],Rest}.
 
-
+getbit(<<>>) ->
+    throw({error,incomplete});
 getbit(Buffer) ->
     <<B:1,Rest/bitstring>> = Buffer,
     {B,Rest}.
 
 
 getbits(Buffer,Num) when is_bitstring(Buffer) ->
+    check_bit_size(Buffer,Num),
     <<Bs:Num,Rest/bitstring>> = Buffer,
     {Bs,Rest}.
 
@@ -237,11 +241,14 @@
 
 %% First align buffer, then pick the first Num octets.
 %% Returns octets as an integer with bit significance as in buffer.
+
 getoctets(Buffer,Num) when is_binary(Buffer) ->
+    check_bin_size(Buffer,Num),
     <<Val:Num/integer-unit:8,RestBin/binary>> = Buffer,
     {Val,RestBin};
 getoctets(Buffer,Num) when is_bitstring(Buffer) ->
     AlignBits = bit_size(Buffer) rem 8,
+    check_bit_size(Buffer,Num*8+AlignBits),
     <<_:AlignBits,Val:Num/integer-unit:8,RestBin/binary>> = Buffer,
     {Val,RestBin}.
 
@@ -249,10 +256,12 @@
 %% First align buffer, then pick the first Num octets.
 %% Returns octets as a binary
 getoctets_as_bin(Bin,Num) when is_binary(Bin) ->
+    check_bin_size(Bin,Num),
     <<Octets:Num/binary,RestBin/binary>> = Bin,
     {Octets,RestBin};
 getoctets_as_bin(Bin,Num) when is_bitstring(Bin) ->
     AlignBits = bit_size(Bin) rem 8,
+    check_bit_size(Bin,AlignBits+Num*8),
     <<_:AlignBits,Val:Num/binary,RestBin/binary>> = Bin,
     {Val,RestBin}.
     
@@ -336,6 +345,7 @@
     exit({error,{asn1,{illegal_value,C,BinBits}}})
     end;
 decode_fragmented_bits(<<0:1,Len:7,Bin/binary>>,C,Acc) ->
+    check_bit_size(Bin,Len),
     <<Value:Len/bitstring,Rest/bitstring>> = Bin,
     BinBits = erlang:list_to_bitstring([Value|Acc]),
     case C of
@@ -349,6 +359,8 @@
 decode_fragmented_octets(Bin,C) ->
     decode_fragmented_octets(Bin,C,[]).
 
+decode_fragmented_octets(<<>>,_C,_Acc) ->
+    throw({error,incomplete});
 decode_fragmented_octets(<<3:2,Len:6,Bin/binary>>,C,Acc) ->
     {Value,Bin2} = split_binary(Bin,Len * ?'16K'),
     decode_fragmented_octets(Bin2,C,[Value|Acc]);
@@ -744,8 +756,9 @@
 dec_integer(<<_:1,B:7,BitStr/bitstring>>) ->
     Size = bit_size(BitStr),
     <<I:Size>> = BitStr,
-    (-128 + B) bsl bit_size(BitStr) bor I.
-
+    (-128 + B) bsl bit_size(BitStr) bor I;
+dec_integer(Bin) when bit_size(Bin) < 8 ->
+    throw({error,incomplete}).
     
     
 decpint(Bin) ->
@@ -811,13 +824,17 @@
 
 decode_length(Buffer,undefined)  -> % un-constrained
     case align(Buffer) of
+ <<>> ->
+    throw({error,incomplete});
  <<0:1,Oct:7,Rest/binary>> ->
     {Oct,Rest};
  <<2:2,Val:14,Rest/binary>> ->
     {Val,Rest};
  <<3:2,_Val:14,_Rest/binary>> ->
     %% this case should be fixed
-    exit({error,{asn1,{decode_length,{nyi,above_16k}}}})
+    exit({error,{asn1,{decode_length,{nyi,above_16k}}}});
+ <<1:1,_:7>> ->
+    throw({error,incomplete})
     end;
 
 decode_length(Buffer,{Lb,Ub}) when Ub =< 65535 ,Lb >= 0 -> % constrained
@@ -837,6 +854,7 @@
 % X.691:10.9.3.5
 decode_length(Bin,{_,_Lb,_Ub}) -> % Unconstrained or large Ub NOTE! this case does not cover case when Ub > 65535
     case Bin of
+ <<>> -> throw({error,incomplete});
  <<0:1,Val:7,Rest/bitstring>> ->
     {Val,Rest};
  _ ->
@@ -844,7 +862,9 @@
  <<2:2,Val:14,Rest/binary>> ->
     {Val,Rest};
  <<3:2,_:14,_Rest/binary>> ->
-    exit({error,{asn1,{decode_length,{nyi,length_above_64K}}}})
+    exit({error,{asn1,{decode_length,{nyi,length_above_64K}}}});
+ <<1:1,_:7>> ->
+    throw({error,incomplete})
     end
     end;
 decode_length(Buffer,SingleValue) when is_integer(SingleValue) ->
@@ -1873,3 +1893,17 @@
     [30,Unused,Len,Val];
 octets_unused_to_complete(Unused,Len,Val) ->
     [31,Unused,<<Len:16>>,Val].
+
+check_bin_size(Binary,ExpectedSize) ->
+    case size(Binary) of
+ Size when Size < ExpectedSize ->
+    throw({error,incomplete});
+ _ -> ok
+    end.
+
+check_bit_size(BitString,ExpectedSize) ->
+    case bit_size(BitString) of
+ BitSize when BitSize < ExpectedSize ->
+    throw({error,incomplete});
+ _ -> ok
+    end.
diff -u old/asn1rt_uper_bin.erl new/asn1rt_uper_bin.erl
--- old/asn1rt_uper_bin.erl 2009-08-18 09:58:25.000000000 +0200
+++ new/asn1rt_uper_bin.erl 2009-08-17 19:32:53.000000000 +0200
@@ -177,33 +177,40 @@
 %% BinBits = binary(),
 %% RestBytes = tuple()
 getbits_as_binary(Num,Bytes) when is_bitstring(Bytes) ->
+    check_bit_size(Bytes,Num),
     <<BS:Num/bitstring,Rest/bitstring>> = Bytes,
     {BS,Rest}.
 
 getbits_as_list(Num,Bytes) when is_bitstring(Bytes) ->
+    check_bit_size(Bytes,Num),
     <<BitStr:Num/bitstring,Rest/bitstring>> = Bytes,
     {[ B || <<B:1>> <= BitStr],Rest}.
 
+getbit(<<>>) ->
+    throw({error,incomplete});
+
 getbit(Buffer) ->
     <<B:1,Rest/bitstring>> = Buffer,
     {B,Rest}.
 
 
 getbits(Buffer,Num) when is_bitstring(Buffer) ->
+    check_bit_size(Buffer,Num),
     <<Bs:Num,Rest/bitstring>> = Buffer,
     {Bs,Rest}.
 
 
-
 %% Pick the first Num octets.
 %% Returns octets as an integer with bit significance as in buffer.
 getoctets(Buffer,Num) when is_bitstring(Buffer) ->
+    check_bin_size(Buffer,Num),
     <<Val:Num/integer-unit:8,RestBitStr/bitstring>> = Buffer,
     {Val,RestBitStr}.
 
 %% Pick the first Num octets.
 %% Returns octets as a binary
 getoctets_as_bin(Bin,Num) when is_bitstring(Bin) ->
+    check_bin_size(Bin,Num),
     <<Octets:Num/binary,RestBin/bitstring>> = Bin,
     {Octets,RestBin}.
 
@@ -265,9 +272,13 @@
 %% If the buffer is not aligned, this function does that.
 decode_fragmented_bits(Buffer,C) ->
     decode_fragmented_bits(Buffer,C,[]).
+
+decode_fragmented_bits(<<>>,_C,[]) ->
+    throw({error, incomplete});
 decode_fragmented_bits(<<3:2,Len:6,BitStr/bitstring>>,C,Acc) ->
 %%    {Value,Bin2} = split_binary(Bin, Len * ?'16K'),
     FragLen = (Len*?'16K') div 8,
+    check_bin_size(BitStr,FragLen),
     <<Value:FragLen/binary,BitStr2/bitstring>> = BitStr,
     decode_fragmented_bits(BitStr2,C,[Value|Acc]);
 decode_fragmented_bits(<<0:1,0:7,BitStr/bitstring>>,C,Acc) ->
@@ -279,6 +290,7 @@
     exit({error,{asn1,{illegal_value,C,BinBits}}})
     end;
 decode_fragmented_bits(<<0:1,Len:7,BitStr/bitstring>>,C,Acc) ->
+    check_bit_size(BitStr,Len),
     <<Val:Len/bitstring,Rest/bitstring>> = BitStr,
 %%    <<Value:Len/binary-unit:1,Bin2/binary>> = Bin,
     ResBitStr = list_to_bitstring(lists:reverse([Val|Acc])),
@@ -293,8 +305,11 @@
 decode_fragmented_octets({0,Bin},C) ->
     decode_fragmented_octets(Bin,C,[]).
 
+decode_fragmented_octets(Bin,_C,[]) when bit_size(Bin) < 8->
+    throw({error, incomplete});
 decode_fragmented_octets(<<3:2,Len:6,BitStr/bitstring>>,C,Acc) ->
     FragLen = Len * ?'16K',
+    check_bin_size(BitStr,FragLen),
     <<Value:FragLen/binary,Rest/bitstring>> = BitStr,
     decode_fragmented_octets(Rest,C,[Value|Acc]);
 decode_fragmented_octets(<<0:1,0:7,Bin/bitstring>>,C,Acc) ->
@@ -306,6 +321,7 @@
     exit({error,{asn1,{illegal_value,C,Octets}}})
     end;
 decode_fragmented_octets(<<0:1,Len:7,BitStr/bitstring>>,C,Acc) ->
+    check_bin_size(BitStr,Len),
     <<Value:Len/binary-unit:8,BitStr2/binary>> = BitStr,
     BinOctets = list_to_binary(lists:reverse([Value|Acc])),
     case C of
@@ -571,13 +587,17 @@
     {Ints,Bytes3} = getoctets_as_bin(Bytes2,Len),
     {dec_integer(Ints),Bytes3}.
 
+dec_integer(Bin) when bit_size(Bin) < 8->
+    throw({error, incomplete});
 dec_integer(Bin = <<0:1,_:7,_/bitstring>>) ->  
     decpint(Bin);
 dec_integer(<<_:1,B:7,BitStr/bitstring>>) ->
     Size = bit_size(BitStr),
     <<I:Size>> = BitStr,
     (-128 + B) bsl bit_size(BitStr) bor I.
-    
+
+decpint(<<>>) ->
+    throw({error, incomplete});
 decpint(Bin) ->
     Size = bit_size(Bin),
     <<Int:Size>> = Bin,
@@ -642,6 +662,10 @@
     {Val,Rest};
 decode_length(<<3:2,_:14,_Rest/bitstring>>,undefined)  ->
     exit({error,{asn1,{decode_length,{nyi,above_16k}}}});
+decode_length(Buffer, undefined) when bit_size(Buffer) < 8 ->
+    throw({error, incomplete});
+decode_length(<<1:1,Rest/bitstring>>,undefined) when bit_size(Rest) < 15 ->
+    throw({error, incomplete});
 
 decode_length(Buffer,{Lb,Ub}) when Ub =< 65535 ,Lb >= 0 -> % constrained
     decode_constrained_number(Buffer,{Lb,Ub});
@@ -661,12 +685,15 @@
  <<2:2,Val:14,Rest/bitstring>> ->
     {Val,Rest};
  <<3:2,_:14,_Rest/bitstring>> ->
-    exit({error,{asn1,{decode_length,{nyi,length_above_64K}}}})
+    exit({error,{asn1,{decode_length,{nyi,length_above_64K}}}});
+ <<1:1,Rest/bitstring>> when bit_size(Rest) < 15 ->
+    throw({error, incomplete});
+        Bin when bit_size(Bin) < 8 ->
+    throw({error, incomplete})
     end;
 decode_length(Buffer,SingleValue) when is_integer(SingleValue) ->
     {SingleValue,Buffer}.
 
-
  % X.691:11
 encode_boolean(true) ->
     <<1:1>>;
@@ -1560,6 +1587,7 @@
 %% decode_real({Name,Val}) -> {REALvalue,Rest}
 decode_real(Bytes) ->
     {Len,Bytes2} = decode_length(Bytes,undefined),
+    check_bin_size(Bytes2,Len),
     <<Bytes3:Len/binary,Rest/bitstring>> = Bytes2,
     {RealVal,Rest,Len} = ?RT_COMMON:decode_real(Bytes3,Len),
     {RealVal,Rest}.
@@ -1633,3 +1661,17 @@
     10;
 num_bits(R) ->
     1+num_bits(R bsr 1).
+
+check_bin_size(Binary,ExpectedSize) ->
+    case size(Binary) of
+ Size when Size < ExpectedSize ->
+    throw({error,incomplete});
+ _ -> ok
+    end.
+
+check_bit_size(BitString,ExpectedSize) ->
+    case bit_size(BitString) of
+ BitSize when BitSize < ExpectedSize ->
+    throw({error,incomplete});
+ _ -> ok
+    end.



________________________________________________________________
erlang-patches mailing list. See http://www.erlang.org/faq.html
erlang-patches (at) erlang.org