Nas*_*out 9 delphi delphi-10-seattle
我正在检查TMemoryStream课程并找到以下例程:
procedure TMemoryStream.LoadFromStream(Stream: TStream);
var
Count: Longint;
begin
Stream.Position := 0;
Count := Stream.Size; // <-- assigning Int64 to Longint
SetSize(Count);
if Count <> 0 then Stream.ReadBuffer(FMemory^, Count);
end;
Run Code Online (Sandbox Code Playgroud)
我已经看到了很多将Int64分配给Longint的模式.
我的理解是在32位和64位Windows 中Longint是4个字节并且Int64是8个字节,所以如果我的文件大小是$1 FFFF FFFF == 8589934591 == 8 GB那么这个例程将无法读取,因为最终计数将是$ FFFF FFFF == -1.
我不明白这是如何允许的,也许不予考虑(可能没有多少人试图读取8 GB以上的文件).
我为此记录了一张票,显然它已在东京 10.2 中修复。这是 64 位编译的问题。
https://quality.embarcadero.com/browse/RSP-19094
TCustomMemoryStream和中的大文件(>2GB)都存在问题TMemoryStream。问题TMemoryStream很简单,因为局部变量需要声明为而NativeInt不是 LongInt,并且容量需要更改为NativeInt. 它们TCustomMemoryStream更加微妙,因为这两种方法都将an-计算TCustomMemoryStream.Read的结果直接分配给 a 。即使计算结果不大于 ,这也会溢出。Int64Int64LongIntLongInt
如果您想在西雅图修复此问题,那么您需要执行代码挂钩、替换 System.Classes 单元或推出您自己的TMemoryStream. 请记住,对于最后一个选项,您还需要替换TBytesStream和TStringStream因为它们源自TMemoryStream.
最后一个选项的另一个问题是第三方组件不会有您的“修复”。对于我们来说,只有几个地方需要处理大于 2GB 的文件,因此我们将这些地方进行了切换。
TCustomMemoryStream.Read 的修复(必须针对这两种方法)将如下所示:
function TCustomMemoryStream.Read(var Buffer; Count: Longint): Longint;
{ These 2 lines are new }
var
remaining: Int64;
begin
if (FPosition >= 0) and (Count >= 0) then
begin
remaining{Result} := FSize - FPosition;
if remaining{Result} > 0 then
begin
if remaining{Result} > Count then
Result := Count
else
Result := remaining;
Move((PByte(FMemory) + FPosition)^, Buffer, Result);
Inc(FPosition, Result);
Exit;
end;
end;
Result := 0;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
284 次 |
| 最近记录: |