DEADSOFTWARE

Net: Realloc outgoing message buffer on overflow
authorfgsfds <pvt.fgsfds@gmail.com>
Sun, 1 Sep 2019 18:33:35 +0000 (21:33 +0300)
committerfgsfds <pvt.fgsfds@gmail.com>
Sun, 1 Sep 2019 18:33:35 +0000 (21:33 +0300)
src/engine/e_msg.pas

index a2ecc52e3e9a40e6a2c58dede4d26344e35847b3..bb7347740bd950401a0bfc4d49626b41c6884069 100644 (file)
@@ -28,6 +28,7 @@ type
     CurSize: Integer;
     ReadCount: Integer;
     Bit: Integer;
+    AllocStep: Integer;
     OwnMemory: Boolean;
 
     function Init(V: Pointer; N: Integer; Full: Boolean = False): Boolean;
@@ -94,6 +95,7 @@ begin
   if P = nil then
     raise Exception.Create('TMsg.Alloc: no mem');
   Init(P, N);
+  AllocStep := N;
   OwnMemory := True;
 end;
 
@@ -141,27 +143,32 @@ begin
 end;
 
 procedure TMsg.WriteData(V: Pointer; N: Integer);
+var
+  NewSize: Integer;
 begin
   if CurSize + N > MaxSize then
   begin
-    Overflow := True;
-    raise Exception.Create('TMsg.WriteData: buffer overrun!');
-    Exit;
+    if OwnMemory then
+    begin
+      NewSize := MaxSize + ((N + AllocStep) div AllocStep) * AllocStep; // round up
+      if ReAllocMem(Data, NewSize) = nil then
+        raise Exception.Create('TMsg.WriteData: out of memory on realloc');
+      MaxSize := NewSize;
+    end
+    else
+    begin
+      Overflow := True;
+      raise Exception.Create('TMsg.WriteData: buffer overrun on borrowed memory!');
+    end;
   end;
+
   Move(V^, (Data + CurSize)^, N);
   CurSize := CurSize + N;
 end;
 
 procedure TMsg.Write(V: TMsg);
 begin
-  if CurSize + V.CurSize > MaxSize then
-  begin
-    Overflow := True;
-    raise Exception.Create('TMsg.WriteData: buffer overrun!');
-    Exit;
-  end;
-  Move(V.Data^, (Data + CurSize)^, V.CurSize);
-  CurSize := CurSize + V.CurSize;
+  WriteData(V.Data, V.CurSize);
 end;
 
 procedure TMsg.Write(V: Byte); overload;