我在分析Oyente的一份合同。合同是:
pragma solidity ^0.4.21;
contract Test{
address admin;
function Test() public{
admin = msg.sender;
}
string str = "";
function setStr(string _str) public{
str = _str;
}
function getStr() public view returns (string){
return str;
}
}
当我把这份合同交给oyente进行分析时,收到了以下报告:
信息:root:contact测试。sol:测试:信息:symExec:=============结果===========信息:symExec:EVM代码覆盖率:24.1%信息:symExec:Integer Underflow:True信息:symExec:整数溢出:True信息:symExec:Parity Multisig Bug 2:错误信息:symExec:调用堆栈深度攻击漏洞:False信息:symExec:事务顺序依赖性(TOD(:False信息:symExec:时间戳相关性:False信息:symExec:重新进入漏洞:False信息:symExec:Test.sol:16:9:警告:整数流量不足。return str如果:return str=1,则发生Integer Underflow信息:symExec:Test.sol:1:5:警告:整数溢出。函数setStr(string_str(public{^跨越多条线。如果:_str=11579208923731619542357098500887907853269984665640564039457584007913129639932,则发生整数溢出信息:symExec:======分析已完成======
它显示字符串变量中的整数上溢和下溢。我真的不明白这是怎么发生的,也不知道该怎么解决。任何帮助都将不胜感激。
这是一个假阳性结果。
string
类型的值存储为字节数组,而不是整数。如果将指定的整数转换为字节数组,然后尝试将其作为string
返回,则该值不可读。
示例:
function getStr2() public view returns (string) {
bytes memory byteArray = abi.encode(115792089237316195423570985008687907853269984665640564039457584007913129639932);
return string(byteArray);
}
在Remix IDE(使用JS VM模拟器和ethers.JS(中失败,错误为:
解码输出失败:null:偏移量0处的无效代码点;错误的代码点前缀(参数="字节",值=Uint8Array(0xffffffffff(,代码=INVALID_argument,版本=字符串/5.5.0(
这表示";字符串";包含一些UTF-8字节,但不以UTF-8 BOM开头。
值1
也是如此。
Solidity字符串跨越多个槽(每个槽有32个字节(,其中第一个槽包含字符串长度。
因此,如果他们将str
值设置为0x01
,这表明数组的长度应该为1。然后,根据他们的模拟器和工具实现,它是:
- 在尝试访问未分配的内存时引发死机错误。他们可能会将其解释为整数下溢,因为这也会导致死机错误
- 或者返回默认槽值
0x0000000000000000000000000000000000000000000000000000000000000000
(32个空字节(,该值仍然不是预期值0x01