From 949491a27e6a392e3ab2c65a46f3203778516901 Mon Sep 17 00:00:00 2001 From: inoussa Date: Sat, 14 Feb 2009 01:10:41 +0000 Subject: [PATCH] Invalid characters handling at the end of base 64 encoded strings. Reported by Birger Jansen, thanks. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@705 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- wst/trunk/basex_encode.pas | 20 +++++++++------ .../tests/test_suite/test_basex_encode.pas | 25 +++++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/wst/trunk/basex_encode.pas b/wst/trunk/basex_encode.pas index 4988e7208..aed721afb 100644 --- a/wst/trunk/basex_encode.pas +++ b/wst/trunk/basex_encode.pas @@ -69,7 +69,7 @@ const IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM, IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM,IM ); - Base64_CHAR_SET = ['A'..'Z','a'..'z','0'..'9','+','/']; + //Base64_CHAR_SET = ['A'..'Z','a'..'z','0'..'9','+','/']; function Base64Encode(const ALength : PtrInt; const AInBuffer) : string; var @@ -139,7 +139,7 @@ var locInQuantom : array[0..3] of Byte; ok : Boolean; locAtualLen : PtrInt; - locInValue : Byte; + locInValue, locReadedValidChars : Byte; locFailOnIllegalChar : Boolean; begin if ( AInBuffer = '' ) then begin @@ -153,6 +153,7 @@ begin locBuffer := @(AInBuffer[1]); locFailOnIllegalChar := not ( xoDecodeIgnoreIllegalChar in AOptions ); while ( locInIndex < locInLen ) do begin + locReadedValidChars := 0; for i := 0 to 3 do begin ok := False; while ( locInIndex <= locInLen ) do begin @@ -172,20 +173,23 @@ begin Inc(locPadded); end; ok := True; + Inc(locReadedValidChars); Break; end else begin if locFailOnIllegalChar then raise EBase64Exception.Create(s_InvalidEncodedData); end; end; - if not ok then + if ( not ok ) and locFailOnIllegalChar then raise EBase64Exception.CreateFmt(s_IllegalChar,[Char(locBuffer^)]); end; - locOutQuantom[0] := ( locInQuantom[0] shl 2 ) or ( locInQuantom[1] shr 4 ); - locOutQuantom[1] := ( locInQuantom[1] shl 4 ) or ( locInQuantom[2] shr 2 ); - locOutQuantom[2] := ( locInQuantom[2] shl 6 ) or ( locInQuantom[3] ); - Move(locOutQuantom[0],Result[locAtualLen],3 - locPadded); - Inc(locAtualLen,3 - locPadded); + if ( locReadedValidChars > 0 ) then begin + locOutQuantom[0] := ( locInQuantom[0] shl 2 ) or ( locInQuantom[1] shr 4 ); + locOutQuantom[1] := ( locInQuantom[1] shl 4 ) or ( locInQuantom[2] shr 2 ); + locOutQuantom[2] := ( locInQuantom[2] shl 6 ) or ( locInQuantom[3] ); + Move(locOutQuantom[0],Result[locAtualLen],3 - locPadded); + Inc(locAtualLen,3 - locPadded); + end; end; SetLength(Result,locAtualLen); end; diff --git a/wst/trunk/tests/test_suite/test_basex_encode.pas b/wst/trunk/tests/test_suite/test_basex_encode.pas index 5e550ff6e..e29b554de 100644 --- a/wst/trunk/tests/test_suite/test_basex_encode.pas +++ b/wst/trunk/tests/test_suite/test_basex_encode.pas @@ -25,6 +25,8 @@ uses type + { TTest_Base64 } + TTest_Base64 = class(TWstBaseTest) protected procedure Check_Encode(const AIn, AExpect : string); @@ -45,6 +47,7 @@ type procedure Decode_fooba(); procedure Decode_foobar(); procedure Decode_illegal_char(); + procedure Decode_empty(); end; TTest_Base16 = class(TWstBaseTest) @@ -133,6 +136,28 @@ begin CheckEquals(True,ok); Check_Decode('Zm9'#200'vY' + sLineBreak + 'm'#0'Fy','foobar',[xoDecodeIgnoreIllegalChar]); + Check_Decode('Zm9'#200'vY' + sLineBreak + 'm'#0'Fy' + sLineBreak,'foobar',[xoDecodeIgnoreIllegalChar]); + Check_Decode('Zm9'#200'vY' + sLineBreak + 'm'#0'Fy' + sLineBreak + sLineBreak,'foobar',[xoDecodeIgnoreIllegalChar]); +end; + +procedure TTest_Base64.Decode_empty(); +var + ok : Boolean; +begin + ok := False; + try + Check_Decode(sLineBreak,'',[]); + except + on e : EBase64Exception do + ok := True; + end; + CheckEquals(True,ok); + + Check_Decode('','',[]); + Check_Decode(#0,'',[xoDecodeIgnoreIllegalChar]); + Check_Decode(sLineBreak,'',[xoDecodeIgnoreIllegalChar]); + Check_Decode(sLineBreak + sLineBreak,'',[xoDecodeIgnoreIllegalChar]); + Check_Decode(sLineBreak + sLineBreak + sLineBreak,'',[xoDecodeIgnoreIllegalChar]); end; procedure TTest_Base64.Encode_empty();