THRIFT-4454 Large writes/reads may cause range check errors in debug mode
Client: Delphi
Patch: Jens Geyer

This closes #1490
diff --git a/lib/delphi/src/Thrift.Stream.pas b/lib/delphi/src/Thrift.Stream.pas
index b6e0cbf..3308c53 100644
--- a/lib/delphi/src/Thrift.Stream.pas
+++ b/lib/delphi/src/Thrift.Stream.pas
@@ -132,6 +132,7 @@
 end;
 
 function TThriftStreamAdapterCOM.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer;
+var pTmp : PByte;
 begin
   inherited;
 
@@ -141,7 +142,9 @@
   Result := 0;
   if FStream <> nil then begin
     if count > 0 then begin
-      FStream.Read( @(PByteArray(pBuf)^[offset]), count, @Result);
+      pTmp := pBuf;
+      Inc( pTmp, offset);
+      FStream.Read( pTmp, count, @Result);
     end;
   end;
 end;
@@ -172,11 +175,14 @@
 
 procedure TThriftStreamAdapterCOM.Write( const pBuf: Pointer; offset: Integer; count: Integer);
 var nWritten : Integer;
+    pTmp : PByte;
 begin
   inherited;
   if IsOpen then begin
     if count > 0 then begin
-      FStream.Write( @(PByteArray(pBuf)^[offset]), count, @nWritten);
+      pTmp := pBuf;
+      Inc( pTmp, offset);
+      FStream.Write( pTmp, count, @nWritten);
     end;
   end;
 end;
@@ -259,14 +265,18 @@
 end;
 
 function TThriftStreamAdapterDelphi.Read(const pBuf : Pointer; const buflen : Integer; offset, count: Integer): Integer;
+var pTmp : PByte;
 begin
   inherited;
 
   if count >= buflen-offset
   then count := buflen-offset;
 
-  if count > 0
-  then Result := FStream.Read( PByteArray(pBuf)^[offset], count)
+  if count > 0 then begin
+    pTmp := pBuf;
+    Inc( pTmp, offset);
+    Result := FStream.Read( pTmp^, count)
+  end
   else Result := 0;
 end;
 
@@ -296,10 +306,13 @@
 end;
 
 procedure TThriftStreamAdapterDelphi.Write(const pBuf : Pointer; offset, count: Integer);
+var pTmp : PByte;
 begin
   inherited;
   if count > 0 then begin
-    FStream.Write( PByteArray(pBuf)^[offset], count)
+    pTmp := pBuf;
+    Inc( pTmp, offset);
+    FStream.Write( pTmp^, count)
   end;
 end;
 
diff --git a/lib/delphi/src/Thrift.Transport.pas b/lib/delphi/src/Thrift.Transport.pas
index 52b617b..d02f0a3 100644
--- a/lib/delphi/src/Thrift.Transport.pas
+++ b/lib/delphi/src/Thrift.Transport.pas
@@ -966,10 +966,11 @@
 var
   nRead : Integer;
   tempbuf : TBytes;
+  pTmp : PByte;
 begin
   inherited;
   Result := 0;
-  
+
   if IsOpen then begin
     while count > 0 do begin
 
@@ -984,8 +985,10 @@
       end;
 
       if FReadBuffer.Position < FReadBuffer.Size then begin
-        nRead  := Min( FReadBuffer.Size - FReadBuffer.Position, count);
-        Inc( Result, FReadBuffer.Read( PByteArray(pBuf)^[offset], nRead));
+        nRead := Min( FReadBuffer.Size - FReadBuffer.Position, count);
+        pTmp  := pBuf;
+        Inc( pTmp, offset);
+        Inc( Result, FReadBuffer.Read( pTmp^, nRead));
         Dec( count, nRead);
         Inc( offset, nRead);
       end;
@@ -1011,11 +1014,14 @@
 end;
 
 procedure TBufferedStreamImpl.Write( const pBuf : Pointer; offset: Integer; count: Integer);
+var pTmp : PByte;
 begin
   inherited;
   if count > 0 then begin
     if IsOpen then begin
-      FWriteBuffer.Write( PByteArray(pBuf)^[offset], count );
+      pTmp := pBuf;
+      Inc( pTmp, offset);
+      FWriteBuffer.Write( pTmp^, count );
       if FWriteBuffer.Size > FBufSize then begin
         Flush;
       end;
@@ -1254,12 +1260,16 @@
 end;
 
 function TFramedTransportImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer;
+var pTmp : PByte;
 begin
   if len > (buflen-off)
   then len := buflen-off;
 
+  pTmp := pBuf;
+  Inc( pTmp, off);
+
   if (FReadBuffer <> nil) and (len > 0) then begin
-    result := FReadBuffer.Read( PByteArray(pBuf)^[off], len);
+    result := FReadBuffer.Read( pTmp^, len);
     if result > 0 then begin
       Exit;
     end;
@@ -1267,7 +1277,7 @@
 
   ReadFrame;
   if len > 0
-  then Result := FReadBuffer.Read( PByteArray(pBuf)^[off], len)
+  then Result := FReadBuffer.Read( pTmp^, len)
   else Result := 0;
 end;
 
@@ -1294,9 +1304,14 @@
 end;
 
 procedure TFramedTransportImpl.Write( const pBuf : Pointer; off, len : Integer);
+var pTmp : PByte;
 begin
-  if len > 0
-  then FWriteBuffer.Write( PByteArray(pBuf)^[off], len );
+  if len > 0 then begin
+    pTmp := pBuf;
+    Inc( pTmp, off);
+
+    FWriteBuffer.Write( pTmp^, len );
+  end;
 end;
 
 { TFramedTransport.TFactory }
@@ -1482,7 +1497,7 @@
     wsaError,
     msecs : Integer;
     nBytes : Integer;
-    pDest : PByte;
+    pTmp : PByte;
 begin
   inherited;
 
@@ -1491,11 +1506,12 @@
   else msecs := DEFAULT_THRIFT_TIMEOUT;
 
   result := 0;
-  pDest := @(PByteArray(pBuf)^[offset]);
+  pTmp   := pBuf;
+  Inc( pTmp, offset);
   while count > 0 do begin
 
     while TRUE do begin
-      wfd := WaitForData( msecs, pDest, count, wsaError, nBytes);
+      wfd := WaitForData( msecs, pTmp, count, wsaError, nBytes);
       case wfd of
         TWaitForData.wfd_Error    :  Exit;
         TWaitForData.wfd_HaveData :  Break;
@@ -1519,8 +1535,8 @@
     msecs := Max( msecs, 200);
 
     ASSERT( nBytes <= count);
-    nBytes := FTcpClient.ReceiveBuf( pDest^, nBytes);
-    Inc( pDest, nBytes);
+    nBytes := FTcpClient.ReceiveBuf( pTmp^, nBytes);
+    Inc( pTmp, nBytes);
     Dec( count, nBytes);
     Inc( result, nBytes);
   end;
@@ -1546,6 +1562,7 @@
 // old sockets version
 var bCanWrite, bError : Boolean;
     retval, wsaError : Integer;
+    pTmp : PByte;
 begin
   inherited;
 
@@ -1566,7 +1583,9 @@
   if bError or not bCanWrite
   then raise TTransportExceptionUnknown.Create('unknown error');
 
-  FTcpClient.SendBuf( PByteArray(pBuf)^[offset], count);
+  pTmp := pBuf;
+  Inc( pTmp, offset);
+  FTcpClient.SendBuf( pTmp^, count);
 end;
 
 {$ELSE}
@@ -1574,16 +1593,17 @@
 function TTcpSocketStreamImpl.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer;
 // new sockets version
 var nBytes : Integer;
-    pDest : PByte;
+    pTmp : PByte;
 begin
   inherited;
 
   result := 0;
-  pDest := @(PByteArray(pBuf)^[offset]);
+  pTmp   := pBuf;
+  Inc( pTmp, offset);
   while count > 0 do begin
-    nBytes := FTcpClient.Read(pDest^, count);
+    nBytes := FTcpClient.Read( pTmp^, count);
     if nBytes = 0 then Exit;
-    Inc( pDest, nBytes);
+    Inc( pTmp, nBytes);
     Dec( count, nBytes);
     Inc( result, nBytes);
   end;
@@ -1610,13 +1630,16 @@
 
 procedure TTcpSocketStreamImpl.Write( const pBuf : Pointer; offset, count: Integer);
 // new sockets version
+var pTmp : PByte;
 begin
   inherited;
 
   if not FTcpClient.IsOpen
   then raise TTransportExceptionNotOpen.Create('not open');
 
-  FTcpClient.Write( PByteArray(pBuf)^[offset], count);
+  pTmp := pBuf;
+  Inc( pTmp, offset);
+  FTcpClient.Write( pTmp^, count);
 end;
 
 {$ENDIF}