Re: [fpc-devel] Overflow in TMemoryStream?

2016-09-14 Thread Martok

> I have committed a patch. Please test and report if it is fixed.
> I don't have a 32-bit system available to test on...
Tested on win32: the overflow is fixed, 500M gets incremented by 125M.

I think the RunError is caused by the way ReallocMem works: growing from 869M to
1086M seems to be done by allocating the new area and copying, so there's a
period of almost all of the 2G heap used...


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Overflow in TMemoryStream?

2016-09-12 Thread Michael Van Canneyt



On Mon, 12 Sep 2016, Michael Van Canneyt wrote:



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.


I have committed a patch. Please test and report if it is fixed.
I don't have a 32-bit system available to test on...

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Overflow in TMemoryStream?

2016-09-12 Thread Michael Van Canneyt



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:
 1   1   13840
 11000   11000   125005824<< grew by 1/4*100M

with ds=500M, prints:
 5   5   52816
 55000   55000   550002688<< bug, grew by 1/10*500M


Output on linux 64-bit

cadwal: >tms
  1   1   13840
  11000   11000   125005824
cadwal: >tms
  5   5   52816
  55000   55000   625004544 This is 1/4
cadwal: >tms
  86900   86900   869003264
  95590   95590  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.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Overflow in TMemoryStream?

2016-09-12 Thread Martok
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:
  1   1   13840
  11000   11000   125005824<< grew by 1/4*100M

with ds=500M, prints:
  5   5   52816
  55000   55000   550002688<< bug, grew by 1/10*500M

However, with ds=869M, prints:
  86900   86900   869003264
  95590 18666185569013440   955904000
and mostly crashes with Runtime Error 203 except when I'm step-by-step-debugging
it...
That looks like a *separate* overflow to me, probably caused by the wild mix of
Int64 and Longint that our Streams inherited from Delphi...

I don't have RTL built with full symbols right now, maybe someone else can
investigate?


Martok

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] Overflow in TMemoryStream?

2016-09-11 Thread Martin Schreiber
Hi,

While working on the MSEgui fork of classes unit I saw a suspect piece of code 
in streams.inc:
"
function TMemoryStream.Realloc(var NewCapacity: PtrInt): Pointer;

begin
  If NewCapacity<0 Then
NewCapacity:=0
  else
begin
  // if growing, grow at least a quarter
  if (NewCapacity>FCapacity) and (NewCapacity < (5*FCapacity) div 4) then
NewCapacity := (5*FCapacity) div 4;
"
Isn't there an overflow if the capacity grows above high(ptrint) div 5 (about 
430MB on 32 bit)?
IIRC there was a discussion on the list about memory problems with big 
TMemoryStream's.

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel