[fpc-devel]Small bugfix for SysUtils.CompareMem

Michalis Kamburelis michalis at camelot.homedns.org
Sat Nov 22 03:04:50 CET 2003


Hi

I just found a bug in CompareMem function in SysUtils.

CompareMem(p1, p2, 0) (third argument = zero) should always return true 
(and ignore values p1 and p2). But, currently, it does not. CompareMem 
is implemented like

function CompareMem(P1, P2: Pointer; Length: cardinal): Boolean;
var
   i: cardinal;
begin
   for i := 0 to Length - 1 do
   begin
     ...
   end;
   Result := True;
end;

so it _looks_ like it's good - when Length=0 then we have
   for i:=0 to -1 do ...
so this loop should never be executed even once. Right ? Wrong. Wrong 
because Length and i are Cardinals (unsigned) and so calculating 
Length-1 gives some extremely big positive value (namely, it's 
High(Length) = $FFFFFFFF) (well, this bug would be catched at runtime by 
compiling RTL with runtime checks for overflow... but RTL is usually 
compiled without these checks).

So CompareMem(..., ..., 0) produces always false or EAccessViolation.

There are many ways to fix this - most elegant for me is to add a line
   if Length = 0 then Exit(true);
at the beginning of this function.

Thanks,
Michalis Kamburelis





More information about the fpc-devel mailing list