|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
[Re] Patch for asn1 libraryHello !
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 |
| Free embeddable forum powered by Nabble | Forum Help |