mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #7091 from ethereum/isoltest-value-format-fix
[isoltest] Fix (aligned) hex parsing and formatting
This commit is contained in:
commit
d44f680a51
@ -101,7 +101,7 @@ contract C {
|
|||||||
// g1() -> FAILURE
|
// g1() -> FAILURE
|
||||||
// h(uint256,uint256): 1, -2 -> 3
|
// h(uint256,uint256): 1, -2 -> 3
|
||||||
// j(bool): true -> false
|
// j(bool): true -> false
|
||||||
// k(bytes32): 0x10 -> 0x10, 0x10
|
// k(bytes32): 0x10001 -> 0x10001, 0x10001
|
||||||
// l(): hex"4200efef" -> 8
|
// l(): hex"4200efef" -> 8
|
||||||
// m(bytes): 32, 32, 0x20 -> 32, 32, 0x20
|
// m(bytes): 32, 32, 0x20 -> 32, 32, 0x20
|
||||||
// m(bytes): 32, 3, hex"AB33BB" -> 32, 3, left(0xAB33BB)
|
// m(bytes): 32, 3, hex"AB33BB" -> 32, 3, left(0xAB33BB)
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include <liblangutil/Common.h>
|
#include <liblangutil/Common.h>
|
||||||
|
|
||||||
|
#include <libdevcore/StringUtils.h>
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -96,10 +98,7 @@ bytes BytesUtils::convertHexNumber(string const& _literal)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_literal.size() % 2)
|
return fromHex(_literal);
|
||||||
throw Error(Error::Type::ParserError, "Hex number encoding invalid.");
|
|
||||||
else
|
|
||||||
return fromHex(_literal);
|
|
||||||
}
|
}
|
||||||
catch (std::exception const&)
|
catch (std::exception const&)
|
||||||
{
|
{
|
||||||
@ -159,13 +158,10 @@ string BytesUtils::formatBoolean(bytes const& _bytes)
|
|||||||
|
|
||||||
string BytesUtils::formatHex(bytes const& _bytes)
|
string BytesUtils::formatHex(bytes const& _bytes)
|
||||||
{
|
{
|
||||||
stringstream os;
|
soltestAssert(!_bytes.empty() && _bytes.size() <= 32, "");
|
||||||
|
u256 value = fromBigEndian<u256>(_bytes);
|
||||||
|
|
||||||
string hex{toHex(_bytes, HexPrefix::Add)};
|
return toCompactHexWithPrefix(value);
|
||||||
boost::algorithm::replace_all(hex, "00", "");
|
|
||||||
os << hex;
|
|
||||||
|
|
||||||
return os.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string BytesUtils::formatHexString(bytes const& _bytes)
|
string BytesUtils::formatHexString(bytes const& _bytes)
|
||||||
|
@ -252,104 +252,97 @@ Parameter TestFileParser::parseParameter()
|
|||||||
parameter.alignment = Parameter::Alignment::Right;
|
parameter.alignment = Parameter::Alignment::Right;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
if (accept(Token::Sub, true))
|
||||||
{
|
{
|
||||||
if (accept(Token::Sub, true))
|
parameter.rawString += formatToken(Token::Sub);
|
||||||
{
|
isSigned = true;
|
||||||
parameter.rawString += formatToken(Token::Sub);
|
|
||||||
isSigned = true;
|
|
||||||
}
|
|
||||||
if (accept(Token::Boolean))
|
|
||||||
{
|
|
||||||
if (isSigned)
|
|
||||||
throw Error(Error::Type::ParserError, "Invalid boolean literal.");
|
|
||||||
|
|
||||||
parameter.abiType = ABIType{ABIType::Boolean, ABIType::AlignRight, 32};
|
|
||||||
string parsed = parseBoolean();
|
|
||||||
parameter.rawString += parsed;
|
|
||||||
parameter.rawBytes = BytesUtils::applyAlign(
|
|
||||||
parameter.alignment,
|
|
||||||
parameter.abiType,
|
|
||||||
BytesUtils::convertBoolean(parsed)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (accept(Token::HexNumber))
|
|
||||||
{
|
|
||||||
if (isSigned)
|
|
||||||
throw Error(Error::Type::ParserError, "Invalid hex number literal.");
|
|
||||||
|
|
||||||
parameter.abiType = ABIType{ABIType::Hex, ABIType::AlignRight, 32};
|
|
||||||
string parsed = parseHexNumber();
|
|
||||||
parameter.rawString += parsed;
|
|
||||||
parameter.rawBytes = BytesUtils::applyAlign(
|
|
||||||
parameter.alignment,
|
|
||||||
parameter.abiType,
|
|
||||||
BytesUtils::convertHexNumber(parsed)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (accept(Token::Hex, true))
|
|
||||||
{
|
|
||||||
if (isSigned)
|
|
||||||
throw Error(Error::Type::ParserError, "Invalid hex string literal.");
|
|
||||||
if (parameter.alignment != Parameter::Alignment::None)
|
|
||||||
throw Error(Error::Type::ParserError, "Hex string literals cannot be aligned or padded.");
|
|
||||||
|
|
||||||
string parsed = parseString();
|
|
||||||
parameter.rawString += "hex\"" + parsed + "\"";
|
|
||||||
parameter.rawBytes = BytesUtils::convertHexNumber(parsed);
|
|
||||||
parameter.abiType = ABIType{
|
|
||||||
ABIType::HexString, ABIType::AlignNone, parameter.rawBytes.size()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (accept(Token::String))
|
|
||||||
{
|
|
||||||
if (isSigned)
|
|
||||||
throw Error(Error::Type::ParserError, "Invalid string literal.");
|
|
||||||
if (parameter.alignment != Parameter::Alignment::None)
|
|
||||||
throw Error(Error::Type::ParserError, "String literals cannot be aligned or padded.");
|
|
||||||
|
|
||||||
string parsed = parseString();
|
|
||||||
parameter.abiType = ABIType{ABIType::String, ABIType::AlignLeft, parsed.size()};
|
|
||||||
parameter.rawString += "\"" + parsed + "\"";
|
|
||||||
parameter.rawBytes = BytesUtils::applyAlign(
|
|
||||||
Parameter::Alignment::Left,
|
|
||||||
parameter.abiType,
|
|
||||||
BytesUtils::convertString(parsed)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (accept(Token::Number))
|
|
||||||
{
|
|
||||||
auto type = isSigned ? ABIType::SignedDec : ABIType::UnsignedDec;
|
|
||||||
|
|
||||||
parameter.abiType = ABIType{type, ABIType::AlignRight, 32};
|
|
||||||
string parsed = parseDecimalNumber();
|
|
||||||
parameter.rawString += parsed;
|
|
||||||
if (isSigned)
|
|
||||||
parsed = "-" + parsed;
|
|
||||||
|
|
||||||
parameter.rawBytes = BytesUtils::applyAlign(
|
|
||||||
parameter.alignment,
|
|
||||||
parameter.abiType,
|
|
||||||
BytesUtils::convertNumber(parsed)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (accept(Token::Failure, true))
|
|
||||||
{
|
|
||||||
if (isSigned)
|
|
||||||
throw Error(Error::Type::ParserError, "Invalid failure literal.");
|
|
||||||
|
|
||||||
parameter.abiType = ABIType{ABIType::Failure, ABIType::AlignRight, 0};
|
|
||||||
parameter.rawBytes = bytes{};
|
|
||||||
}
|
|
||||||
if (parameter.alignment != Parameter::Alignment::None)
|
|
||||||
{
|
|
||||||
expect(Token::RParen);
|
|
||||||
parameter.rawString += formatToken(Token::RParen);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (std::exception const&)
|
if (accept(Token::Boolean))
|
||||||
{
|
{
|
||||||
throw Error(Error::Type::ParserError, "Literal encoding invalid.");
|
if (isSigned)
|
||||||
|
throw Error(Error::Type::ParserError, "Invalid boolean literal.");
|
||||||
|
|
||||||
|
parameter.abiType = ABIType{ABIType::Boolean, ABIType::AlignRight, 32};
|
||||||
|
string parsed = parseBoolean();
|
||||||
|
parameter.rawString += parsed;
|
||||||
|
parameter.rawBytes = BytesUtils::applyAlign(
|
||||||
|
parameter.alignment,
|
||||||
|
parameter.abiType,
|
||||||
|
BytesUtils::convertBoolean(parsed)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (accept(Token::HexNumber))
|
||||||
|
{
|
||||||
|
if (isSigned)
|
||||||
|
throw Error(Error::Type::ParserError, "Invalid hex number literal.");
|
||||||
|
|
||||||
|
parameter.abiType = ABIType{ABIType::Hex, ABIType::AlignRight, 32};
|
||||||
|
string parsed = parseHexNumber();
|
||||||
|
parameter.rawString += parsed;
|
||||||
|
parameter.rawBytes = BytesUtils::applyAlign(
|
||||||
|
parameter.alignment,
|
||||||
|
parameter.abiType,
|
||||||
|
BytesUtils::convertHexNumber(parsed)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (accept(Token::Hex, true))
|
||||||
|
{
|
||||||
|
if (isSigned)
|
||||||
|
throw Error(Error::Type::ParserError, "Invalid hex string literal.");
|
||||||
|
if (parameter.alignment != Parameter::Alignment::None)
|
||||||
|
throw Error(Error::Type::ParserError, "Hex string literals cannot be aligned or padded.");
|
||||||
|
|
||||||
|
string parsed = parseString();
|
||||||
|
parameter.rawString += "hex\"" + parsed + "\"";
|
||||||
|
parameter.rawBytes = BytesUtils::convertHexNumber(parsed);
|
||||||
|
parameter.abiType = ABIType{
|
||||||
|
ABIType::HexString, ABIType::AlignNone, parameter.rawBytes.size()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (accept(Token::String))
|
||||||
|
{
|
||||||
|
if (isSigned)
|
||||||
|
throw Error(Error::Type::ParserError, "Invalid string literal.");
|
||||||
|
if (parameter.alignment != Parameter::Alignment::None)
|
||||||
|
throw Error(Error::Type::ParserError, "String literals cannot be aligned or padded.");
|
||||||
|
|
||||||
|
string parsed = parseString();
|
||||||
|
parameter.abiType = ABIType{ABIType::String, ABIType::AlignLeft, parsed.size()};
|
||||||
|
parameter.rawString += "\"" + parsed + "\"";
|
||||||
|
parameter.rawBytes = BytesUtils::applyAlign(
|
||||||
|
Parameter::Alignment::Left,
|
||||||
|
parameter.abiType,
|
||||||
|
BytesUtils::convertString(parsed)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (accept(Token::Number))
|
||||||
|
{
|
||||||
|
auto type = isSigned ? ABIType::SignedDec : ABIType::UnsignedDec;
|
||||||
|
|
||||||
|
parameter.abiType = ABIType{type, ABIType::AlignRight, 32};
|
||||||
|
string parsed = parseDecimalNumber();
|
||||||
|
parameter.rawString += parsed;
|
||||||
|
if (isSigned)
|
||||||
|
parsed = "-" + parsed;
|
||||||
|
|
||||||
|
parameter.rawBytes = BytesUtils::applyAlign(
|
||||||
|
parameter.alignment,
|
||||||
|
parameter.abiType,
|
||||||
|
BytesUtils::convertNumber(parsed)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (accept(Token::Failure, true))
|
||||||
|
{
|
||||||
|
if (isSigned)
|
||||||
|
throw Error(Error::Type::ParserError, "Invalid failure literal.");
|
||||||
|
|
||||||
|
parameter.abiType = ABIType{ABIType::Failure, ABIType::AlignRight, 0};
|
||||||
|
parameter.rawBytes = bytes{};
|
||||||
|
}
|
||||||
|
if (parameter.alignment != Parameter::Alignment::None)
|
||||||
|
{
|
||||||
|
expect(Token::RParen);
|
||||||
|
parameter.rawString += formatToken(Token::RParen);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parameter;
|
return parameter;
|
||||||
|
@ -404,6 +404,27 @@ BOOST_AUTO_TEST_CASE(call_arguments_string)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(call_hex_number)
|
||||||
|
{
|
||||||
|
char const* source = R"(
|
||||||
|
// f(bytes32, bytes32): 0x616, 0x1042 -> 1
|
||||||
|
)";
|
||||||
|
auto const calls = parse(source);
|
||||||
|
BOOST_REQUIRE_EQUAL(calls.size(), 1);
|
||||||
|
testFunctionCall(
|
||||||
|
calls.at(0),
|
||||||
|
Mode::SingleLine,
|
||||||
|
"f(bytes32,bytes32)",
|
||||||
|
false,
|
||||||
|
fmt::encodeArgs(
|
||||||
|
fromHex("0x616"),
|
||||||
|
fromHex("0x1042")
|
||||||
|
),
|
||||||
|
fmt::encodeArgs(1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(call_return_string)
|
BOOST_AUTO_TEST_CASE(call_return_string)
|
||||||
{
|
{
|
||||||
char const* source = R"(
|
char const* source = R"(
|
||||||
@ -786,14 +807,6 @@ BOOST_AUTO_TEST_CASE(call_ether_type_invalid)
|
|||||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(call_hex_number_invalid)
|
|
||||||
{
|
|
||||||
char const* source = R"(
|
|
||||||
// f(bytes32, bytes32): 0x616, 0x042 -> 1
|
|
||||||
)";
|
|
||||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(call_signed_bool_invalid)
|
BOOST_AUTO_TEST_CASE(call_signed_bool_invalid)
|
||||||
{
|
{
|
||||||
char const* source = R"(
|
char const* source = R"(
|
||||||
|
@ -193,7 +193,7 @@ string TestFunctionCall::formatBytesParameters(
|
|||||||
fill_n(
|
fill_n(
|
||||||
back_inserter(defaultParameters),
|
back_inserter(defaultParameters),
|
||||||
ceil(_bytes.size() / 32),
|
ceil(_bytes.size() / 32),
|
||||||
Parameter{bytes(), "", ABIType{ABIType::UnsignedDec}, FormatInfo{}}
|
Parameter{bytes(), "", ABIType{ABIType::Hex}, FormatInfo{}}
|
||||||
);
|
);
|
||||||
ContractABIUtils::overwriteParameters(_errorReporter, defaultParameters, _parameters);
|
ContractABIUtils::overwriteParameters(_errorReporter, defaultParameters, _parameters);
|
||||||
os << BytesUtils::formatBytesRange(_bytes, defaultParameters, _highlight);
|
os << BytesUtils::formatBytesRange(_bytes, defaultParameters, _highlight);
|
||||||
|
@ -139,7 +139,8 @@ BOOST_AUTO_TEST_CASE(format_hex_singleline)
|
|||||||
BOOST_REQUIRE_EQUAL(test.format(), "// f(bytes32): 0x31 -> 0x31");
|
BOOST_REQUIRE_EQUAL(test.format(), "// f(bytes32): 0x31 -> 0x31");
|
||||||
|
|
||||||
bytes actualResult = fromHex("0x32");
|
bytes actualResult = fromHex("0x32");
|
||||||
bytes actualBytes = actualResult + bytes(32 - actualResult.size(), 0);
|
bytes actualBytes = bytes(32 - actualResult.size(), 0) + actualResult;
|
||||||
|
|
||||||
test.setRawBytes(actualBytes);
|
test.setRawBytes(actualBytes);
|
||||||
test.setFailure(false);
|
test.setFailure(false);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user