数年没发帖了,上来特别提醒DELPHI用户注意这个问题。在调用System.ZLib.ZDecompressStream时,某些情况可能陷入死循环,无法退出。
procedure ZDecompressStream(inStream, outStream: TStream);
const
bufferSize = 32768;
var
zstream: TZStreamRec;
zresult: Integer;
inBuffer: TBytes;
outBuffer: TBytes;
inSize: Integer;
outSize: Integer;
begin
SetLength(inBuffer, BufferSize);
SetLength(outBuffer, BufferSize);
FillChar(zstream, SizeOf(TZStreamRec), 0); ZDecompressCheck(InflateInit(zstream)); try
inSize := inStream.Read(inBuffer, bufferSize);
while inSize > 0 do
begin
zstream.next_in := @inBuffer[0];
zstream.avail_in := inSize; repeat
zstream.next_out := @outBuffer[0];
zstream.avail_out := bufferSize; ZDecompressCheckWithoutBufferError(inflate(zstream, Z_NO_FLUSH)); outSize := bufferSize - zstream.avail_out; outStream.Write(outBuffer, outSize);
until (zstream.avail_in = 0) and (zstream.avail_out > 0); inSize := inStream.Read(inBuffer, bufferSize);
end; repeat
zstream.next_out := @outBuffer[0];
zstream.avail_out := bufferSize; zresult := ZDecompressCheckWithoutBufferError(inflate(zstream, Z_FINISH)); <-------------- outSize := bufferSize - zstream.avail_out; outStream.Write(outBuffer, outSize);
until (zresult = Z_STREAM_END) and (zstream.avail_out > 0);
finally
ZDecompressCheck(inflateEnd(zstream));
end;
end;
function ZDecompressCheckWithoutBufferError(code: Integer): Integer; overload;
begin
Result := code; if code < 0 then
if (code <> Z_BUF_ERROR) then <------------罪魁祸首
raise EZDecompressionError.Create(string(_z_errmsg[2 - code]));
end;尚不清楚XE 10.2.3的ZLib代码为什么在code = Z_BUF_ERROR的时候,不抛出异常。导致的后果是一直在repeat中死循环。
procedure ZDecompressStream(inStream, outStream: TStream);
const
bufferSize = 32768;
var
zstream: TZStreamRec;
zresult: Integer;
inBuffer: TBytes;
outBuffer: TBytes;
inSize: Integer;
outSize: Integer;
begin
SetLength(inBuffer, BufferSize);
SetLength(outBuffer, BufferSize);
FillChar(zstream, SizeOf(TZStreamRec), 0); ZDecompressCheck(InflateInit(zstream)); try
inSize := inStream.Read(inBuffer, bufferSize);
while inSize > 0 do
begin
zstream.next_in := @inBuffer[0];
zstream.avail_in := inSize; repeat
zstream.next_out := @outBuffer[0];
zstream.avail_out := bufferSize; ZDecompressCheckWithoutBufferError(inflate(zstream, Z_NO_FLUSH)); outSize := bufferSize - zstream.avail_out; outStream.Write(outBuffer, outSize);
until (zstream.avail_in = 0) and (zstream.avail_out > 0); inSize := inStream.Read(inBuffer, bufferSize);
end; repeat
zstream.next_out := @outBuffer[0];
zstream.avail_out := bufferSize; zresult := ZDecompressCheckWithoutBufferError(inflate(zstream, Z_FINISH)); <-------------- outSize := bufferSize - zstream.avail_out; outStream.Write(outBuffer, outSize);
until (zresult = Z_STREAM_END) and (zstream.avail_out > 0);
finally
ZDecompressCheck(inflateEnd(zstream));
end;
end;
function ZDecompressCheckWithoutBufferError(code: Integer): Integer; overload;
begin
Result := code; if code < 0 then
if (code <> Z_BUF_ERROR) then <------------罪魁祸首
raise EZDecompressionError.Create(string(_z_errmsg[2 - code]));
end;尚不清楚XE 10.2.3的ZLib代码为什么在code = Z_BUF_ERROR的时候,不抛出异常。导致的后果是一直在repeat中死循环。
解决方案 »
- 求一个sql语句!!着急!!在线等!!(求新客户个数)
- adoquery插入语句的问题,急,请高手帮忙!
- 这条语句为什么不执行?
- 请那位大侠告诉我,这样的软件界面的主窗体是用何种控件所做?
- 求《Mastering Delphi 5》的英文电子书
- Delphi6中INDY控件組是作什麼用的?如MD5是不是加密控件?
- 送分的问题,过来看看
- 请问在Delphi6中网络数据库与本地数据库之间如何转换
- Delphi AccessViolation at address 00000000
- MessageBox
- delphi 用VMP加密,加入asm,64位报错,32位没问题,有解决办法吗?
- delphi工具栏上的checkbox为什么有个像分割条的竖线
procedure ZDecompressStream(inStream, outStream: TStream);
const
bufferSize = 32768;
var
zstream: TZStreamRec;
zresult: Integer;
inBuffer: array[0..bufferSize - 1] of AnsiChar;
outBuffer: array[0..bufferSize - 1] of AnsiChar;
inSize: Integer;
outSize: Integer;
begin
FillChar(zstream, SizeOf(TZStreamRec), 0); ZCompressCheck(InflateInit(zstream)); inSize := inStream.Read(inBuffer, bufferSize); while inSize > 0 do
begin
zstream.next_in := inBuffer;
zstream.avail_in := inSize; repeat
zstream.next_out := outBuffer;
zstream.avail_out := bufferSize; ZCompressCheck(inflate(zstream, Z_NO_FLUSH)); // outSize := zstream.next_out - outBuffer;
outSize := bufferSize - zstream.avail_out; outStream.Write(outBuffer, outSize);
until (zstream.avail_in = 0) and (zstream.avail_out > 0); inSize := inStream.Read(inBuffer, bufferSize);
end; repeat
zstream.next_out := outBuffer;
zstream.avail_out := bufferSize; zresult := ZCompressCheck(inflate(zstream, Z_FINISH)); // outSize := zstream.next_out - outBuffer;
outSize := bufferSize - zstream.avail_out; outStream.Write(outBuffer, outSize);
until (zresult = Z_STREAM_END) and (zstream.avail_out > 0); ZCompressCheck(inflateEnd(zstream));
end;
function ZCompressCheck(code: Integer): Integer;
begin
result := code; if code < 0 then
begin
raise EZCompressionError.Create(_z_errmsg[2 - code]);
end;
end;function ZDecompressCheck(code: Integer): Integer;
begin
Result := code; if code < 0 then
begin
raise EZDecompressionError.Create(_z_errmsg[2 - code]);
end;
end;
raise EZDecompressionError.Create(string(_z_errmsg[2 - code])); 上面应当是if code = Z_BUF_ERROR) then
raise EZDecompressionError.Create(string(_z_errmsg[2 - code]));
逻辑上才行得通
你的问题估计是其他原因导致的。