From 10667e0b4139530898f65f10c214ccb6c6aadbfb Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 10 Feb 2015 09:00:50 +0100 Subject: [PATCH] Tests and some code for msg.data. --- libsolidity/AST.cpp | 3 ++- libsolidity/Types.cpp | 14 +++++++++++++- libsolidity/Types.h | 2 +- test/SolidityEndToEndTest.cpp | 25 +++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 041b6277d..33cf8c12d 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -403,7 +403,8 @@ void Assignment::checkTypeRequirements() m_leftHandSide->checkTypeRequirements(); m_leftHandSide->requireLValue(); //@todo later, assignments to structs might be possible, but not to mappings - if (!m_leftHandSide->getType()->isValueType() && !m_leftHandSide->isLocalLValue()) + if (m_leftHandSide->getType()->getCategory() != Type::Category::ByteArray && + !m_leftHandSide->getType()->isValueType() && !m_leftHandSide->isLocalLValue()) BOOST_THROW_EXCEPTION(createTypeError("Assignment to non-local non-value lvalue.")); m_type = m_leftHandSide->getType(); if (m_assigmentOperator == Token::Assign) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 069493e62..9faa3f3c0 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -508,6 +508,16 @@ TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const return _operator == Token::Delete ? make_shared() : TypePointer(); } +bool ByteArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const +{ + if (*this == _convertTo) + return true; + if (_convertTo.getCategory() != Category::ByteArray) + return false; + auto const& other = dynamic_cast(_convertTo); + return (m_dynamicLength == other.m_dynamicLength || m_length == other.m_length); +} + bool ByteArrayType::operator==(Type const& _other) const { if (_other.getCategory() != getCategory()) @@ -952,7 +962,9 @@ MagicType::MagicType(MagicType::Kind _kind): case Kind::Message: m_members = MemberList({{"sender", make_shared(0, IntegerType::Modifier::Address)}, {"gas", make_shared(256)}, - {"value", make_shared(256)}}); + {"value", make_shared(256)}, + {"data", make_shared(ByteArrayType::Location::CallData, + 0, 0, true)}}); break; case Kind::Transaction: m_members = MemberList({{"origin", make_shared(0, IntegerType::Modifier::Address)}, diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 927ca2902..ddcfad9ed 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -287,11 +287,11 @@ public: virtual Category getCategory() const override { return Category::ByteArray; } ByteArrayType(Location _location, u256 const& _offset, u256 const& _length, bool _dynamicLength): m_location(_location), m_offset(_offset), m_length(_length), m_dynamicLength(_dynamicLength) {} + virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; virtual bool operator==(const Type& _other) const override; virtual unsigned getSizeOnStack() const override { return 1; /* TODO */ } virtual std::string toString() const override { return "bytes"; } - private: Location m_location; u256 m_offset; diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 8a21290cb..054b0c6a4 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -2254,6 +2254,31 @@ BOOST_AUTO_TEST_CASE(generic_call) BOOST_CHECK_EQUAL(m_state.balance(m_contractAddress), 50 - 2); } +BOOST_AUTO_TEST_CASE(storing_bytes) +{ + char const* sourceCode = R"( + contract C { + function save() { + savedData = msg.data; + } + function forward() { + this.call(savedData); + } + function clear() { + delete savedData; + } + function doubleIt(uint a) returns (uint b) { return a * 2; } + bytes savedData; + } + )"; + compileAndRun(sourceCode); + FixedHash<4> innerHash(dev::sha3("doubleIt(uint256)")); + BOOST_CHECK(callContractFunction("save()", innerHash.asBytes(), 7) == bytes()); + BOOST_CHECK(callContractFunction("forward()") == encodeArgs(14)); + BOOST_CHECK(callContractFunction("clear()") == bytes()); + BOOST_CHECK(callContractFunction("forward()") == bytes()); +} + BOOST_AUTO_TEST_SUITE_END() }