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}