From e206ad6c24202d1769d8967898b9cedb3d43e4e0 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 7 Aug 2019 12:15:10 +0200 Subject: [PATCH 1/3] [isoltest] Fixes hex (plus alignment) formatting. --- test/libsolidity/semanticTests/smoke_test.sol | 2 +- test/libsolidity/util/BytesUtils.cpp | 11 ++++------- test/libsolidity/util/TestFunctionCall.cpp | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/test/libsolidity/semanticTests/smoke_test.sol b/test/libsolidity/semanticTests/smoke_test.sol index 07cd79d0f..82f38656f 100644 --- a/test/libsolidity/semanticTests/smoke_test.sol +++ b/test/libsolidity/semanticTests/smoke_test.sol @@ -101,7 +101,7 @@ contract C { // g1() -> FAILURE // h(uint256,uint256): 1, -2 -> 3 // j(bool): true -> false -// k(bytes32): 0x10 -> 0x10, 0x10 +// k(bytes32): 0x1001 -> 0x1001, 0x1001 // l(): hex"4200efef" -> 8 // m(bytes): 32, 32, 0x20 -> 32, 32, 0x20 // m(bytes): 32, 3, hex"AB33BB" -> 32, 3, left(0xAB33BB) diff --git a/test/libsolidity/util/BytesUtils.cpp b/test/libsolidity/util/BytesUtils.cpp index dd2a5166b..61ecead30 100644 --- a/test/libsolidity/util/BytesUtils.cpp +++ b/test/libsolidity/util/BytesUtils.cpp @@ -21,6 +21,8 @@ #include +#include + #include #include @@ -159,13 +161,8 @@ string BytesUtils::formatBoolean(bytes const& _bytes) string BytesUtils::formatHex(bytes const& _bytes) { - stringstream os; - - string hex{toHex(_bytes, HexPrefix::Add)}; - boost::algorithm::replace_all(hex, "00", ""); - os << hex; - - return os.str(); + u256 value = fromBigEndian(_bytes); + return toCompactHexWithPrefix(value); } string BytesUtils::formatHexString(bytes const& _bytes) diff --git a/test/libsolidity/util/TestFunctionCall.cpp b/test/libsolidity/util/TestFunctionCall.cpp index d22c3b3f0..272950782 100644 --- a/test/libsolidity/util/TestFunctionCall.cpp +++ b/test/libsolidity/util/TestFunctionCall.cpp @@ -193,7 +193,7 @@ string TestFunctionCall::formatBytesParameters( fill_n( back_inserter(defaultParameters), ceil(_bytes.size() / 32), - Parameter{bytes(), "", ABIType{ABIType::UnsignedDec}, FormatInfo{}} + Parameter{bytes(), "", ABIType{ABIType::Hex}, FormatInfo{}} ); ContractABIUtils::overwriteParameters(_errorReporter, defaultParameters, _parameters); os << BytesUtils::formatBytesRange(_bytes, defaultParameters, _highlight); From fe15db65376255d2fce0ee6bbab7e433d73a2e46 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 7 Aug 2019 12:22:52 +0200 Subject: [PATCH 2/3] [isoltest] Fixes exception handling while parsing literals. --- test/libsolidity/util/TestFileParser.cpp | 183 +++++++++++------------ 1 file changed, 88 insertions(+), 95 deletions(-) diff --git a/test/libsolidity/util/TestFileParser.cpp b/test/libsolidity/util/TestFileParser.cpp index bd283960e..ebb865b4f 100644 --- a/test/libsolidity/util/TestFileParser.cpp +++ b/test/libsolidity/util/TestFileParser.cpp @@ -252,104 +252,97 @@ Parameter TestFileParser::parseParameter() parameter.alignment = Parameter::Alignment::Right; } - try + if (accept(Token::Sub, true)) { - if (accept(Token::Sub, 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); - } + parameter.rawString += formatToken(Token::Sub); + isSigned = true; } - 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; From 5ca991ac81be3fcb9e6c5589d062a18bc293227d Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Fri, 12 Jul 2019 13:58:31 +0200 Subject: [PATCH 3/3] [isoltest] Allows odd-sized hex literals. --- test/libsolidity/semanticTests/smoke_test.sol | 2 +- test/libsolidity/util/BytesUtils.cpp | 7 ++--- test/libsolidity/util/TestFileParserTests.cpp | 29 ++++++++++++++----- .../util/TestFunctionCallTests.cpp | 3 +- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/test/libsolidity/semanticTests/smoke_test.sol b/test/libsolidity/semanticTests/smoke_test.sol index 82f38656f..23ad109a0 100644 --- a/test/libsolidity/semanticTests/smoke_test.sol +++ b/test/libsolidity/semanticTests/smoke_test.sol @@ -101,7 +101,7 @@ contract C { // g1() -> FAILURE // h(uint256,uint256): 1, -2 -> 3 // j(bool): true -> false -// k(bytes32): 0x1001 -> 0x1001, 0x1001 +// k(bytes32): 0x10001 -> 0x10001, 0x10001 // l(): hex"4200efef" -> 8 // m(bytes): 32, 32, 0x20 -> 32, 32, 0x20 // m(bytes): 32, 3, hex"AB33BB" -> 32, 3, left(0xAB33BB) diff --git a/test/libsolidity/util/BytesUtils.cpp b/test/libsolidity/util/BytesUtils.cpp index 61ecead30..82d70dcb9 100644 --- a/test/libsolidity/util/BytesUtils.cpp +++ b/test/libsolidity/util/BytesUtils.cpp @@ -98,10 +98,7 @@ bytes BytesUtils::convertHexNumber(string const& _literal) { try { - if (_literal.size() % 2) - throw Error(Error::Type::ParserError, "Hex number encoding invalid."); - else - return fromHex(_literal); + return fromHex(_literal); } catch (std::exception const&) { @@ -161,7 +158,9 @@ string BytesUtils::formatBoolean(bytes const& _bytes) string BytesUtils::formatHex(bytes const& _bytes) { + soltestAssert(!_bytes.empty() && _bytes.size() <= 32, ""); u256 value = fromBigEndian(_bytes); + return toCompactHexWithPrefix(value); } diff --git a/test/libsolidity/util/TestFileParserTests.cpp b/test/libsolidity/util/TestFileParserTests.cpp index 21e185bae..72ac9210d 100644 --- a/test/libsolidity/util/TestFileParserTests.cpp +++ b/test/libsolidity/util/TestFileParserTests.cpp @@ -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) { char const* source = R"( @@ -786,14 +807,6 @@ BOOST_AUTO_TEST_CASE(call_ether_type_invalid) 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) { char const* source = R"( diff --git a/test/libsolidity/util/TestFunctionCallTests.cpp b/test/libsolidity/util/TestFunctionCallTests.cpp index 090e95399..9f67c7b91 100644 --- a/test/libsolidity/util/TestFunctionCallTests.cpp +++ b/test/libsolidity/util/TestFunctionCallTests.cpp @@ -139,7 +139,8 @@ BOOST_AUTO_TEST_CASE(format_hex_singleline) BOOST_REQUIRE_EQUAL(test.format(), "// f(bytes32): 0x31 -> 0x31"); bytes actualResult = fromHex("0x32"); - bytes actualBytes = actualResult + bytes(32 - actualResult.size(), 0); + bytes actualBytes = bytes(32 - actualResult.size(), 0) + actualResult; + test.setRawBytes(actualBytes); test.setFailure(false);