Merge pull request #14500 from ethereum/fix-isoltest-update-loop-on-short-expectations

Fix infinite isoltest expectation update loop on values not taking full slots
This commit is contained in:
Kamil Śliwak 2023-08-21 14:19:20 +02:00 committed by GitHub
commit ee21b03e6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -26,6 +26,8 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <algorithm>
#include <iterator>
#include <iomanip> #include <iomanip>
#include <memory> #include <memory>
#include <regex> #include <regex>
@ -253,26 +255,46 @@ std::string BytesUtils::formatFixedPoint(bytes const& _bytes, bool _signed, size
string BytesUtils::formatRawBytes( string BytesUtils::formatRawBytes(
bytes const& _bytes, bytes const& _bytes,
solidity::frontend::test::ParameterList const& _parameters, solidity::frontend::test::ParameterList const& _parameters,
string _linePrefix) string _linePrefix
)
{ {
stringstream os; stringstream os;
ParameterList parameters; ParameterList parameters;
auto it = _bytes.begin(); auto it = _bytes.begin();
if (_bytes.size() != ContractABIUtils::encodingSize(_parameters)) if (_bytes.size() != ContractABIUtils::encodingSize(_parameters))
parameters = ContractABIUtils::defaultParameters((_bytes.size() + 31) / 32); {
// Interpret all full 32-byte values as integers.
parameters = ContractABIUtils::defaultParameters(_bytes.size() / 32);
// We'd introduce trailing zero bytes if we interpreted the final bit as an integer.
// We want a right-aligned sequence of bytes instead.
if (_bytes.size() % 32 != 0)
parameters.push_back({
bytes(),
"",
ABIType{ABIType::HexString, ABIType::AlignRight, _bytes.size() % 32},
FormatInfo{},
});
}
else else
parameters = _parameters; parameters = _parameters;
soltestAssert(ContractABIUtils::encodingSize(parameters) >= _bytes.size());
for (auto const& parameter: parameters) for (auto const& parameter: parameters)
{ {
bytes byteRange{it, it + static_cast<long>(parameter.abiType.size)}; long actualSize = min(
distance(it, _bytes.end()),
static_cast<ParameterList::difference_type>(parameter.abiType.size)
);
bytes byteRange(parameter.abiType.size, 0);
copy(it, it + actualSize, byteRange.begin());
os << _linePrefix << byteRange; os << _linePrefix << byteRange;
if (&parameter != &parameters.back()) if (&parameter != &parameters.back())
os << endl; os << endl;
it += static_cast<long>(parameter.abiType.size); it += actualSize;
} }
return os.str(); return os.str();
@ -365,14 +387,32 @@ string BytesUtils::formatBytesRange(
auto it = _bytes.begin(); auto it = _bytes.begin();
if (_bytes.size() != ContractABIUtils::encodingSize(_parameters)) if (_bytes.size() != ContractABIUtils::encodingSize(_parameters))
parameters = ContractABIUtils::defaultParameters((_bytes.size() + 31) / 32); {
// Interpret all full 32-byte values as integers.
parameters = ContractABIUtils::defaultParameters(_bytes.size() / 32);
// We'd introduce trailing zero bytes if we interpreted the final bit as an integer.
// We want a right-aligned sequence of bytes instead.
if (_bytes.size() % 32 != 0)
parameters.push_back({
bytes(),
"",
ABIType{ABIType::HexString, ABIType::AlignRight, _bytes.size() % 32},
FormatInfo{},
});
}
else else
parameters = _parameters; parameters = _parameters;
soltestAssert(ContractABIUtils::encodingSize(parameters) >= _bytes.size());
for (auto const& parameter: parameters) for (auto const& parameter: parameters)
{ {
bytes byteRange{it, it + static_cast<long>(parameter.abiType.size)}; long actualSize = min(
distance(it, _bytes.end()),
static_cast<ParameterList::difference_type>(parameter.abiType.size)
);
bytes byteRange(parameter.abiType.size, 0);
copy(it, it + actualSize, byteRange.begin());
if (!parameter.matchesBytes(byteRange)) if (!parameter.matchesBytes(byteRange))
AnsiColorized( AnsiColorized(
@ -386,7 +426,7 @@ string BytesUtils::formatBytesRange(
if (&parameter != &parameters.back()) if (&parameter != &parameters.back())
os << ", "; os << ", ";
it += static_cast<long>(parameter.abiType.size); it += actualSize;
} }
return os.str(); return os.str();