You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[AUD-029] [INFO] Signed conversion has no slow-reference differential fuzz (unsigned has LibParseDecimalSlow) #99
The unsigned conversion has a spec-derived slow reference (LibParseDecimalSlow) fuzzed over arbitrary and digit-dense bytes, but the signed conversion has none — its coverage is a targeted branch matrix (all branches are individually discriminated: sign consumption, both overflow boundaries including int256 min, error propagation for all three selectors, lone '-', '+', '--'). The asymmetry means a future edit to the signed wrapper is protected only by the enumerated cases, not by an oracle over arbitrary input.
Proposed fix
Extend test/lib/parse/LibParseDecimalSlow.sol with a signed reference and fuzz it from the existing signed test contract:
function decimalStringToSignedIntSlow(bytes memory data) internal pure returns (bytes4, int256) {
if (data.length == 0) {
return (ParseEmptyDecimalString.selector, 0);
}
bool isNeg = data[0] == "-";
bytes memory digits = data;
if (isNeg) {
digits = new bytes(data.length - 1);
for (uint256 i = 0; i < digits.length; i++) {
digits[i] = data[i + 1];
}
}
(bytes4 errorSelector, uint256 value) = decimalStringToIntSlow(digits);
if (errorSelector != bytes4(0)) {
return (errorSelector, 0);
}
if (isNeg) {
if (value > uint256(type(int256).max) + 1) {
return (ParseDecimalOverflow.selector, 0);
}
if (value == uint256(type(int256).max) + 1) {
return (bytes4(0), type(int256).min);
}
// forge-lint: disable-next-line(unsafe-typecast)
return (bytes4(0), -int256(value));
}
if (value > uint256(type(int256).max)) {
return (ParseDecimalOverflow.selector, 0);
}
// forge-lint: disable-next-line(unsafe-typecast)
return (bytes4(0), int256(value));
}
// In TestLibParseDecimalUnsafeDecimalStringToSignedInt:
function testUnsafeStrToSignedIntReference(bytes memory data) external pure {
(bytes4 slowSelector, int256 slowValue) = LibParseDecimalSlow.decimalStringToSignedIntSlow(data);
(bytes4 errorSelector, int256 result) = LibParseDecimal.unsafeDecimalStringToSignedInt(
Pointer.unwrap(data.dataPointer()), Pointer.unwrap(data.endDataPointer())
);
assertEq(errorSelector, slowSelector);
assertEq(result, slowValue);
}
Activity