[fpc-devel] Overflow in TMemoryStream?
Michael Van Canneyt
michael at freepascal.org
Mon Sep 12 10:38:27 CEST 2016
On Sun, 11 Sep 2016, Martok wrote:
> Hi,
>
> yes, I can confirm this as an overflow, but on its own, it should be safe. Above
> 430MB, the stream doesn't grow by a quarter but just by however much was
> requested, luckily the branch fails before the wrong capacity could be set.
>
> Test:
> type
> TMS2 = class(TMemoryStream) end;
> var
> ms: TMS2;
> ds: Int64;
> begin
> ds:= 100*1000*1000;
> ms:= TMS2.Create;
> ms.SetSize(ds);
> WriteLn(ds:15,' ', ms.Size:15, ' ', ms.Capacity:15);
> inc(ds, ds div 10); // grow by less than 25%
> ms.SetSize(ds);
> WriteLn(ds:15,' ', ms.Size:15, ' ', ms.Capacity:15);
> end.
>
> with ds=100M, prints:
> 100000000 100000000 100003840
> 110000000 110000000 125005824 << grew by 1/4*100M
>
> with ds=500M, prints:
> 500000000 500000000 500002816
> 550000000 550000000 550002688 << bug, grew by 1/10*500M
Output on linux 64-bit
cadwal: >tms
100000000 100000000 100003840
110000000 110000000 125005824
cadwal: >tms
500000000 500000000 500002816
550000000 550000000 625004544 This is 1/4
cadwal: >tms
869000000 869000000 869003264
955900000 955900000 1086255104
So it looks like a 32 vs. 64 bit issue.
from the method Realloc :
NewCapacity := (5*FCapacity) div 4; // 5*FCapacity can cause overflow
Changing this to
NewCapacity:=FCapacity + (FCapacity div 4)
Will probably fix the issue.
Michael.
More information about the fpc-devel
mailing list