This is a piece of code of md5 unit:
function MDFile(const Filename: RawByteString; const Version: TMDVersion; const BufSize: PtrUInt): TMDDigest;
var
F: File;
Buf: Pchar;
Context: TMDContext;
Count: Cardinal;
ofm: Longint;
begin
MDInit(Context, Version);
Assign(F, Filename);
{$push}{$i-}
ofm := FileMode;
FileMode := 0;
Reset(F, 1);
{$pop}
if IOResult = 0 then
begin
GetMem(Buf, BufSize);
repeat
BlockRead(F, Buf^, Bufsize, Count);
if Count > 0 then
MDUpdate(Context, Buf^, Count);
until Count < BufSize;
FreeMem(Buf, BufSize);
Close(F);
end;
MDFinal(Context, Result);
FileMode := ofm;
The problem is that if IOResult is <> 0 then md5 is not computed but the function produces a result anyway, without raising any exception.
I suggest this:
[...]
a:=IOResult;
if a = 0 then
begin
GetMem(Buf, BufSize);
repeat
BlockRead(F, Buf^, Bufsize, Count);
if Count > 0 then
MDUpdate(Context, Buf^, Count);
until Count < BufSize;
FreeMem(Buf, BufSize);
Close(F);
MDFinal(Context, Result);
end
else
begin
for a := 0 to length(Result)-1 do Result[a]:=0;
end;
FileMode := ofm;
end;
In this way, if opening file fails,the result is a string of zeros and the caller can detect the issue.
Moreover I see that Reset and BlockRead cannot read path+filenames longer than 256 character. But this case in linux happens often because, when you use an external hard disk it is usually mounted with UUID in the path, and so a lot of characters are wasted.
Thank you