gpt4 book ai didi

delphi - 在 Stream.read 中使用 Longint 计数和 Int64 大小不是很危险吗?

转载 作者:行者123 更新时间:2023-12-03 14:44:36 25 4
gpt4 key购买 nike

我正在检查 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;

我经常看到这种模式,其中将 Int64 分配给 Longint。

我的理解是Longint是四个字节和 Int64在 32 位和 64 位 Windows 中都是 8 个字节,因此如果我的文件大小为 $1 FFFF FFFF == 8589934591 == 8 GB 那么此例程将无法读取,因为最终计数将为$FFFF FFFF == -1

我不明白这是如何允许的,并且可能没有考虑到(也许没有多少人尝试读取 8+ GB 文件)。

最佳答案

我为此记录了一张票,它显然已在东京 10.2 中修复。这是 64 位编译的问题。

https://quality.embarcadero.com/browse/RSP-19094

TCustomMemoryStreamTMemoryStream 中的大文件 (>2GB) 都存在问题。在TMemoryStream中,问题很简单,因为局部变量需要声明为NativeInt而不是LongInt,并且Capacity需要更改为NativeInt。在 TCustomMemoryStream 中,它们更加微妙,因为两个 TCustomMemoryStream.Read 方法都直接分配 Int64 - Int64 计算的结果到 LongInt。即使计算结果不大于 LongInt,也会溢出。

如果您想在西雅图解决此问题,那么您需要执行代码 Hook 、替换 System.Classes 单元或为 TMemoryStream 推出您自己的替换类。请记住,对于最后一个选项,您还需要替换 TBytesStreamTStringStream,因为它们源自 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;

关于delphi - 在 Stream.read 中使用 Longint 计数和 Int64 大小不是很危险吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48039254/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com