Delphi Alexandria中Lockbox3计算MD5触发Integer overflow异常求助
Delphi Alexandria环境下Lockbox3 MD5哈希代码触发Integer overflow异常
我使用Lockbox3已有多年,此前在Delphi XE7环境下使用(版本约为3.4,源码中未找到版本号)。现在迁移至Delphi Alexandria,采用Getit包管理器提供的Lockbox3版本,执行代码时在MyHash.HashAnsiString(src);处触发了Integer overflow异常。
我的代码如下:
function TForm1.md5(src: string): string; function Display(Buf: TBytes): String; var i: Integer; begin Result := ''; for i := 0 to 15 do Result := Result + Format('%0.2x', [Buf[i]]); Result := LowerCase(Trim(Result)); end; var output : AnsiString; bytes : TBytes; P, Sz: integer; aByte: byte; s: string; MyHash : THash; Lib : TCryptographicLibrary; begin Lib := TCryptographicLibrary.Create(nil); MyHash := THash.Create(nil); MyHash.CryptoLibrary := Lib; MyHash.HashId := 'native.hash.MD5'; MyHash.Begin_Hash; MyHash.HashAnsiString(src); if not assigned(MyHash.HashOutputValue) then output := 'nil' else begin SetLength(Bytes, 16); Sz := MyHash.HashOutputValue.Size; if Sz <> 16 then output := Format('wrong size: %d', [Sz]) else begin P := 0; MyHash.HashOutputValue.Position := 0; while MyHash.HashOutputValue.Read(aByte, 1) = 1 do begin bytes[P] := aByte; Inc(P); end; result := Display(Bytes); end; end; MyHash.Destroy; Lib.Destroy; end;
问题原因与解决方法
1. 核心原因
Delphi Alexandria默认字符串为UnicodeString,而HashAnsiString方法接收AnsiString参数。隐式类型转换时,新版本Lockbox3的内部长度处理逻辑发生变化,导致整数溢出。此外旧代码缺少显式的哈希收尾调用,也可能引发资源或计算状态异常。
2. 修复方案
替换哈希方法并补全流程
- 用
HashString替代HashAnsiString:该方法专门适配Unicode字符串,无需类型转换 - 显式调用
End_Hash:新版本Lockbox3需要手动结束哈希计算,确保输出值正确生成 - 简化结果读取:直接使用
HashOutputValue.AsBytes获取字节数组,避免手动流读取的冗余代码
修改后的完整函数:
function TForm1.md5(src: string): string; function Display(Buf: TBytes): String; var i: Integer; begin Result := ''; for i := 0 to High(Buf) do Result := Result + Format('%0.2x', [Buf[i]]); Result := LowerCase(Trim(Result)); end; var MyHash : THash; Lib : TCryptographicLibrary; HashBytes: TBytes; begin Lib := TCryptographicLibrary.Create(nil); try MyHash := THash.Create(nil); try MyHash.CryptoLibrary := Lib; MyHash.HashId := 'native.hash.MD5'; MyHash.Begin_Hash; MyHash.HashString(src); // 适配Unicode字符串的哈希方法 MyHash.End_Hash; // 显式结束哈希计算 HashBytes := MyHash.HashOutputValue.AsBytes; if Length(HashBytes) = 16 then Result := Display(HashBytes) else Result := Format('wrong size: %d', [Length(HashBytes)]); finally MyHash.Free; // 用Free替代Destroy,更符合Delphi资源管理规范 end; finally Lib.Free; end; end;
额外优化点
- 使用
try...finally块管理资源:避免代码异常时出现内存泄漏,比直接调用Destroy更安全 - 遍历字节数组改用
High(Buf):避免硬编码16位长度,适配其他哈希算法的结果长度
内容的提问来源于stack exchange,提问作者MSSI
相关产品推荐
相关产品推荐

