The TPSTypeRec.CalcSize calculated the element size for base types btProcPtr and btPointer as 20 bytes under 64-bit, however it was assumed to be 24 bytes in several other places, thus leading to buffer overruns. This fix supersedes the patch for issue #150, changing the element size for both base types to 24 bytes and adjusting the code that previously assumed a size of 20 bytes. 32-bit code is not affected, since the element size was (and still is) 12 bytes in all cases. (#152)

An alternative approach would have been to fix all the places that previously treated the element size as 24 (as in the patch for issue #150), however an element size of 20 leads to misaligned pointers in array entries.

Signed-off-by: Pierre le Riche <git@pleasedontspam.me>
This commit is contained in:
Pierre le Riche 2017-06-12 14:45:29 +02:00 committed by Carlo Kok
parent d428ecc59f
commit 8bd6ea180f

View File

@ -1711,9 +1711,9 @@ begin
{$ENDIF}{$IFNDEF PS_NOINTERFACES}btInterface, {$ENDIF}
btclass, btPChar, btString: FrealSize := PointerSize;
btSingle, bts32, btU32: FRealSize := 4;
btProcPtr: FRealSize := 2 * sizeof(Pointer) + sizeof(Cardinal);
btProcPtr: FRealSize := 3 * sizeof(Pointer);
btCurrency: FrealSize := Sizeof(Currency);
btPointer: FRealSize := 2 * sizeof(Pointer) + sizeof(LongBool); // ptr, type, freewhendone
btPointer: FRealSize := 3 * sizeof(Pointer); // ptr, type, freewhendone
btDouble{$IFNDEF PS_NOINT64}, bts64{$ENDIF}: FrealSize := 8;
btExtended: FrealSize := SizeOf(Extended);
btReturnAddress: FrealSize := Sizeof(TBTReturnAddress);
@ -1777,13 +1777,13 @@ begin
begin
Pointer(p^) := nil;
Pointer(Pointer(IPointer(p)+PointerSize)^) := nil;
LongBool(Pointer(IPointer(p)+(2*PointerSize))^) := False;
Pointer(Pointer(IPointer(p)+(2*PointerSize))^) := nil;
end;
btProcPtr:
begin
Longint(p^) := 0;
Pointer(Pointer(IPointer(p)+PointerSize)^) := nil;
Cardinal(Pointer(IPointer(p)+(2*PointerSize))^) := 0;
Pointer(Pointer(IPointer(p)+(2*PointerSize))^) := nil;
end;
btCurrency: tbtCurrency(P^) := 0;
btDouble{$IFNDEF PS_NOINT64}, bts64{$ENDIF}: {$IFNDEF PS_NOINT64}tbtS64(P^) := 0{$ELSE}tbtdouble(p^) := 0 {$ENDIF};
@ -3942,8 +3942,8 @@ begin
for i := 0 to Len -1 do
begin
tbtU32(Dest^) := tbtU32(Src^);
Dest := Pointer(IPointer(Dest) + 4);
Src := Pointer(IPointer(Src) + 4);
Dest := Pointer(IPointer(Dest) + PointerSize);
Src := Pointer(IPointer(Src) + PointerSize);
Pointer(Dest^) := Pointer(Src^);
Dest := Pointer(IPointer(Dest) + PointerSize);
Src := Pointer(IPointer(Src) + PointerSize);
@ -4112,9 +4112,9 @@ begin
Pointer(Dest^) := Pointer(Src^);
Dest := Pointer(IPointer(Dest) + PointerSize);
Src := Pointer(IPointer(Src) + PointerSize);
LongBool(Dest^) := false;
Dest := Pointer(IPointer(Dest) + sizeof(LongBool));
Src := Pointer(IPointer(Src) + sizeof(LongBool));
Pointer(Dest^) := nil;
Dest := Pointer(IPointer(Dest) + PointerSize);
Src := Pointer(IPointer(Src) + PointerSize);
end;
end else begin
for i := 0 to Len -1 do
@ -4145,8 +4145,8 @@ begin
Pointer(Pointer(IPointer(Dest) + PointerSize)^) := nil;
Pointer(Pointer(IPointer(Dest) + PointerSize2)^) := nil;
end;
Dest := Pointer(IPointer(Dest) + PointerSize*2+sizeof(LongBool));
Src := Pointer(IPointer(Src) + PointerSize*2+sizeof(LongBool));
Dest := Pointer(IPointer(Dest) + PointerSize*3);
Src := Pointer(IPointer(Src) + PointerSize*3);
end;
end;
end;
@ -9688,7 +9688,7 @@ begin
{$ENDIF}
end;
end;
datap := Pointer(IPointer(datap)+ (2*sizeof(Pointer)+sizeof(Longbool)));
datap := Pointer(IPointer(datap)+ (3*sizeof(Pointer)));
p := PansiChar(p) + Result^.ElementSize;
end;
end;
@ -9804,7 +9804,7 @@ begin
{$ENDIF}
{$ENDIF}
end;
datap := Pointer(IPointer(datap)+ (2*sizeof(Pointer)+sizeof(LongBool)));
datap := Pointer(IPointer(datap)+ (3*sizeof(Pointer)));
p := Pointer(IPointer(p) + Cardinal(v^.ElementSize));
end;
FreeMem(v.Data, v.ElementSize * v.ItemCount);
@ -12738,7 +12738,7 @@ end;
procedure TPSTypeRec_ProcPtr.CalcSize;
begin
FRealSize := 2 * sizeof(Pointer) + Sizeof(Cardinal);
FRealSize := 3 * sizeof(Pointer);
end;
end.