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


_______________________________________________ fpc-devel maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to