turbodelphiのindyのTIdSASLCRAMMD5を以下のソースで利用するとアドレス00000000のエラーが発生します。ソースたどるとfree命令で止まっているようです。
delphi6で同じソースでは問題なく動作するのですが、どなたが原因を知っておられる方おられるでしょうか?
---------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var ss,aa :string;
const a = 'aaaaaaa';
begin
IdSASLCRAMMD51 := TIdSASLCRAMMD5.Create;
IdUserPassProvider1 := TIdUserPassProvider.Create;
IdSASLCRAMMD51.UserPassProvider := TIdUserPassProvider.Create;
IdSASLCRAMMD51.UserPassProvider := IdUserPassProvider1;
ss := IdSASLCRAMMD51.StartAuthenticate(a);
showmessage('ss = ' + ss);
end;
アドレス00000000のエラーは、オブジェクトがない場合によく発生します。
BDS2006だと
const付きのTestだと異常終了せず、Const無しのTest2だと異常終了する
D7では両方異常終了しない。
type
TA = array of Byte;
procedure TEST(const A: TA);
begin
MessageBox(0,PChar(A),'',0);
end;
procedure TEST2(A: TA);
begin
MessageBox(0,PChar(A),'',0);
end;
procedure TForm7.Button2Click(Sender: TObject);
var
MemoryStream : TMemoryStream;
begin
MemoryStream := TMemoryStream.Create;
MemoryStream.Write('ABCDE'#0#0,7);
Test2(MemoryStream.Memory);
MemoryStream.Free;
end;
バグなのか?
var にすると D7 , BDS ともに異常終了するみたい
procedure TEST3(var A: TA);
begin
MessageBox(0,PChar(A),'',0);
end;
A := MemoryStream.Memory;
Test3(A);
Indy9がインストールされている状態で
Indy10をLibにコピーして試しただけだけど
なのでこんな感じなのかな?
CopyTIdBytes は IBGlobal.pas に定義されている関数だけど
class function TIdSASLCRAMMD5.BuildKeydMD5Auth(const Password, Challenge: string): string;
のローカル関数にしても良いとも思うけど
他の所で使っている場合そこでも異常終了しそうだけど
procedure CopyTIdBytes(const ASource: TIdBytes; const ASourceIndex: Integer;
const VDest: TIdBytes; const ADestIndex: Integer; const ALength: Integer);
var
I : Integer;
begin
//if this assert fails, then it indicates an attempted read-past-end-of-buffer.
Assert(ALength<=Length(aSource));
//Move(ASource[ASourceIndex], VDest[ADestIndex], ALength);
for I:=0 to ALength -1 do
begin
VDest[ADestIndex] := ASource[ASourceIndex];
end;
end;
IdZeroMemory は元々ローカル関数なので他に影響なし
// Zero out a memory zone
procedure IdZeroMemory(const Dest: TIdbytes; Length: Integer);
begin
CopyTIdBytes(ToBytes(StringOfChar(#0, Length)), 0, Dest , 0, Length);
end;
IdZeroMemory(AKey.Memory, AKey.Size);
で AKey.Memory から Akey.Size 分 Zero にしているだけだから
ここで関数呼ばずに初期化しても良さそうだけど
私も調べました結論はKHE00221さんと同感でした。
BuildKeydMD5Auth関数内のローカル関数 IdZeroMemory(メモリの初期化)にAkey.memory(TIdMemoryStream)を入れた時にエラーになります。delphi6だと通りましたが。原因は良くわかりませんが。
解決法はKHE00221さんの指摘されるとおり、IdZeroMemoryはいらないので、そこをコメントアウトすればエラーは発生しなく、また結果の方もdelphi6での結果と等しいので問題はないと思います。KHE00221さんありがとうございまた。
ツイート | ![]() |