mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fixes #10299 - Common function for library address validation
This commit is contained in:
parent
09038ce4cb
commit
f3e8dfdaca
@ -31,6 +31,7 @@
|
||||
|
||||
#include <libevmasm/Disassemble.h>
|
||||
|
||||
#include <libsolutil/Address.h>
|
||||
#include <libsmtutil/Exceptions.h>
|
||||
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
@ -888,31 +889,11 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
|
||||
{
|
||||
if (!jsonSourceName[library].isString())
|
||||
return formatFatalError(Error::Type::JSONError, "Library address must be a string.");
|
||||
string address = jsonSourceName[library].asString();
|
||||
|
||||
if (!boost::starts_with(address, "0x"))
|
||||
return formatFatalError(
|
||||
Error::Type::JSONError,
|
||||
"Library address is not prefixed with \"0x\"."
|
||||
);
|
||||
|
||||
if (address.length() != 42)
|
||||
return formatFatalError(
|
||||
Error::Type::JSONError,
|
||||
"Library address is of invalid length."
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
ret.libraries[sourceName + ":" + library] = util::h160(address);
|
||||
}
|
||||
catch (util::BadHexCharacter const&)
|
||||
{
|
||||
return formatFatalError(
|
||||
Error::Type::JSONError,
|
||||
"Invalid library address (\"" + address + "\") supplied."
|
||||
);
|
||||
}
|
||||
std::string addrString = jsonSourceName[library].asString();
|
||||
util::Result<util::h160> addrResult = util::validateAddress(addrString);
|
||||
if (!addrResult.message().empty())
|
||||
return formatFatalError(Error::Type::JSONError, addrResult.message());
|
||||
ret.libraries[sourceName + ":" + library] = addrResult.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
73
libsolutil/Address.cpp
Normal file
73
libsolutil/Address.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
#include <libsolutil/Address.h>
|
||||
#include <libsolutil/Exceptions.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace solidity::util
|
||||
{
|
||||
|
||||
/// @returns a h160 representation of an address string
|
||||
/// or an error message in case the address string is not a valid address
|
||||
Result<h160> validateAddress(string _addrString)
|
||||
{
|
||||
string message;
|
||||
h160 address;
|
||||
|
||||
if (_addrString.substr(0, 2) != "0x")
|
||||
message = "Library address \"" + _addrString + "\" is not prefixed with \"0x\".\n"
|
||||
"Note that the address must be prefixed with \"0x\".";
|
||||
else
|
||||
{
|
||||
string addrString = _addrString.substr(2);
|
||||
|
||||
if (addrString.length() != 40)
|
||||
message =
|
||||
"Invalid library address length " +
|
||||
to_string(addrString.length()) +
|
||||
" instead of 40 characters.";
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
address = util::h160(_addrString);
|
||||
}
|
||||
catch (util::BadHexCharacter const&)
|
||||
{
|
||||
message = "Invalid library address (\"" + _addrString + "\") supplied.";
|
||||
}
|
||||
}
|
||||
|
||||
if (message.empty())
|
||||
{
|
||||
if (!passesAddressChecksum(addrString, false))
|
||||
message =
|
||||
"Invalid checksum for library address \"" + _addrString + "\".\n"
|
||||
"The correct checksum is \"" + getChecksummedAddress(addrString) + "\".";
|
||||
}
|
||||
}
|
||||
|
||||
if (!message.empty())
|
||||
return Result<h160>::err(message);
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
}
|
32
libsolutil/Address.h
Normal file
32
libsolutil/Address.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libsolutil/Common.h>
|
||||
#include <libsolutil/Result.h>
|
||||
#include <libsolutil/FixedHash.h>
|
||||
|
||||
namespace solidity::util
|
||||
{
|
||||
|
||||
/// @returns a h160 representation of an address string
|
||||
/// or an error message in case the address string is not a valid address
|
||||
Result<h160> validateAddress(std::string _addrString);
|
||||
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
set(sources
|
||||
Address.cpp
|
||||
Address.h
|
||||
Algorithms.h
|
||||
AnsiColorized.h
|
||||
Assertions.h
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
|
||||
#include <libsolutil/Address.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <range/v3/view/transform.hpp>
|
||||
@ -417,36 +419,10 @@ void CommandLineParser::parseLibraryOption(string const& _input)
|
||||
"Note that there should not be any whitespace after the " +
|
||||
(isSeparatorEqualSign ? "equal sign" : "colon") + "."
|
||||
);
|
||||
|
||||
if (addrString.substr(0, 2) == "0x")
|
||||
addrString = addrString.substr(2);
|
||||
else
|
||||
solThrow(
|
||||
CommandLineValidationError,
|
||||
"The address " + addrString + " is not prefixed with \"0x\".\n"
|
||||
"Note that the address must be prefixed with \"0x\"."
|
||||
);
|
||||
|
||||
if (addrString.length() != 40)
|
||||
solThrow(
|
||||
CommandLineValidationError,
|
||||
"Invalid length for address for library \"" + libName + "\": " +
|
||||
to_string(addrString.length()) + " instead of 40 characters."
|
||||
);
|
||||
if (!util::passesAddressChecksum(addrString, false))
|
||||
solThrow(
|
||||
CommandLineValidationError,
|
||||
"Invalid checksum on address for library \"" + libName + "\": " + addrString + "\n"
|
||||
"The correct checksum is " + util::getChecksummedAddress(addrString)
|
||||
);
|
||||
bytes binAddr = util::fromHex(addrString);
|
||||
util::h160 address(binAddr, util::h160::AlignRight);
|
||||
if (binAddr.size() > 20 || address == util::h160())
|
||||
solThrow(
|
||||
CommandLineValidationError,
|
||||
"Invalid address for library \"" + libName + "\": " + addrString
|
||||
);
|
||||
m_options.linker.libraries[libName] = address;
|
||||
util::Result<util::h160> addrResult = util::validateAddress(addrString);
|
||||
if (!addrResult.message().empty())
|
||||
solThrow(CommandLineValidationError, "Library \"" + libName + "\": " + addrResult.message());
|
||||
m_options.linker.libraries[libName] = addrResult.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
1
test/cmdlineTests/linking_solidity_wrong_references/args
Normal file
1
test/cmdlineTests/linking_solidity_wrong_references/args
Normal file
@ -0,0 +1 @@
|
||||
--bin --bin-runtime --libraries linking_solidity_wrong_references/input.sol:L=0x12345678901234567890123456789012345678AB linking_solidity_wrong_references/input.sol:L1=0x12345678901234567890123456789012345678Ab linking_solidity_wrong_references/input.sol:L2=0x12345678901234567890123456789012345678A sol:L3=x12345678901234567890123456789012345678AB linking_solidity_wrong_references/input.sol:L4=012345678901234567890123456789012345678AB linking_solidity_wrong_references/input.sol:L5=0x linking_solidity_wrong_references/input.sol:L6=0x0
|
@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.0;
|
||||
|
||||
library L {
|
||||
function f() external {}
|
||||
}
|
||||
|
||||
library L1 {
|
||||
function f() external {}
|
||||
}
|
||||
|
||||
library L2 {
|
||||
function f() external {}
|
||||
}
|
||||
|
||||
library L3 {
|
||||
function f() external {}
|
||||
}
|
||||
|
||||
library L4 {
|
||||
function f() external {}
|
||||
}
|
||||
|
||||
library L5 {
|
||||
function f() external {}
|
||||
}
|
||||
|
||||
library L6 {
|
||||
function f() external {}
|
||||
}
|
||||
|
||||
contract C {
|
||||
function foo() public {
|
||||
L.f();
|
||||
L1.f();
|
||||
L2.f();
|
||||
L3.f();
|
||||
L4.f();
|
||||
L5.f();
|
||||
L6.f();
|
||||
}
|
||||
}
|
62
test/cmdlineTests/linking_solidity_wrong_references/output
Normal file
62
test/cmdlineTests/linking_solidity_wrong_references/output
Normal file
@ -0,0 +1,62 @@
|
||||
|
||||
======= linking_solidity_wrong_references/input.sol:C =======
|
||||
Binary:
|
||||
<BYTECODE REMOVED>__$58d585080104a63ea16eac081c26fdeb7d$__<BYTECODE REMOVED>__$1618aeda50b2dcc26f161cca5d8e112b6f$__<BYTECODE REMOVED>__$265f2a239eabe0580e9e3f71486a88d62d$__<BYTECODE REMOVED>__$5c806807d1dd49cf7e0831ce4f7c3e225c$__<BYTECODE REMOVED>__$305390516cf3f93dc14e593f5c3a7ccd6a$__<BYTECODE REMOVED>__$23207ce64f0ebdd09636cf18c59a1ef8a8$__<BYTECODE REMOVED>
|
||||
|
||||
// $58d585080104a63ea16eac081c26fdeb7d$ -> linking_solidity_wrong_references/input.sol:L1
|
||||
// $1618aeda50b2dcc26f161cca5d8e112b6f$ -> linking_solidity_wrong_references/input.sol:L2
|
||||
// $265f2a239eabe0580e9e3f71486a88d62d$ -> linking_solidity_wrong_references/input.sol:L3
|
||||
// $5c806807d1dd49cf7e0831ce4f7c3e225c$ -> linking_solidity_wrong_references/input.sol:L4
|
||||
// $305390516cf3f93dc14e593f5c3a7ccd6a$ -> linking_solidity_wrong_references/input.sol:L5
|
||||
// $23207ce64f0ebdd09636cf18c59a1ef8a8$ -> linking_solidity_wrong_references/input.sol:L6
|
||||
Binary of the runtime part:
|
||||
<BYTECODE REMOVED>__$58d585080104a63ea16eac081c26fdeb7d$__<BYTECODE REMOVED>__$1618aeda50b2dcc26f161cca5d8e112b6f$__<BYTECODE REMOVED>__$265f2a239eabe0580e9e3f71486a88d62d$__<BYTECODE REMOVED>__$5c806807d1dd49cf7e0831ce4f7c3e225c$__<BYTECODE REMOVED>__$305390516cf3f93dc14e593f5c3a7ccd6a$__<BYTECODE REMOVED>__$23207ce64f0ebdd09636cf18c59a1ef8a8$__<BYTECODE REMOVED>
|
||||
|
||||
// $58d585080104a63ea16eac081c26fdeb7d$ -> linking_solidity_wrong_references/input.sol:L1
|
||||
// $1618aeda50b2dcc26f161cca5d8e112b6f$ -> linking_solidity_wrong_references/input.sol:L2
|
||||
// $265f2a239eabe0580e9e3f71486a88d62d$ -> linking_solidity_wrong_references/input.sol:L3
|
||||
// $5c806807d1dd49cf7e0831ce4f7c3e225c$ -> linking_solidity_wrong_references/input.sol:L4
|
||||
// $305390516cf3f93dc14e593f5c3a7ccd6a$ -> linking_solidity_wrong_references/input.sol:L5
|
||||
// $23207ce64f0ebdd09636cf18c59a1ef8a8$ -> linking_solidity_wrong_references/input.sol:L6
|
||||
|
||||
======= linking_solidity_wrong_references/input.sol:L =======
|
||||
Binary:
|
||||
<BYTECODE REMOVED>
|
||||
Binary of the runtime part:
|
||||
<BYTECODE REMOVED>
|
||||
|
||||
======= linking_solidity_wrong_references/input.sol:L1 =======
|
||||
Binary:
|
||||
<BYTECODE REMOVED>
|
||||
Binary of the runtime part:
|
||||
<BYTECODE REMOVED>
|
||||
|
||||
======= linking_solidity_wrong_references/input.sol:L2 =======
|
||||
Binary:
|
||||
<BYTECODE REMOVED>
|
||||
Binary of the runtime part:
|
||||
<BYTECODE REMOVED>
|
||||
|
||||
======= linking_solidity_wrong_references/input.sol:L3 =======
|
||||
Binary:
|
||||
<BYTECODE REMOVED>
|
||||
Binary of the runtime part:
|
||||
<BYTECODE REMOVED>
|
||||
|
||||
======= linking_solidity_wrong_references/input.sol:L4 =======
|
||||
Binary:
|
||||
<BYTECODE REMOVED>
|
||||
Binary of the runtime part:
|
||||
<BYTECODE REMOVED>
|
||||
|
||||
======= linking_solidity_wrong_references/input.sol:L5 =======
|
||||
Binary:
|
||||
<BYTECODE REMOVED>
|
||||
Binary of the runtime part:
|
||||
<BYTECODE REMOVED>
|
||||
|
||||
======= linking_solidity_wrong_references/input.sol:L6 =======
|
||||
Binary:
|
||||
<BYTECODE REMOVED>
|
||||
Binary of the runtime part:
|
||||
<BYTECODE REMOVED>
|
@ -853,7 +853,7 @@ BOOST_AUTO_TEST_CASE(libraries_invalid_length)
|
||||
}
|
||||
)";
|
||||
Json::Value result = compile(input);
|
||||
BOOST_CHECK(containsError(result, "JSONError", "Library address is of invalid length."));
|
||||
BOOST_CHECK(containsError(result, "JSONError", "Invalid library address length 2 instead of 40 characters."));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(libraries_missing_hex_prefix)
|
||||
@ -876,7 +876,32 @@ BOOST_AUTO_TEST_CASE(libraries_missing_hex_prefix)
|
||||
}
|
||||
)";
|
||||
Json::Value result = compile(input);
|
||||
BOOST_CHECK(containsError(result, "JSONError", "Library address is not prefixed with \"0x\"."));
|
||||
BOOST_CHECK(containsError(result, "JSONError",
|
||||
"Library address \"4200000000000000000000000000000000000001\" is not prefixed with \"0x\".\nNote that the address must be prefixed with \"0x\"."));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(libraries_invalid_ckecsum)
|
||||
{
|
||||
char const* input = R"(
|
||||
{
|
||||
"language": "Solidity",
|
||||
"settings": {
|
||||
"libraries": {
|
||||
"library.sol": {
|
||||
"L": "0x42000000000000000000000000000000000000Ab"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sources": {
|
||||
"empty": {
|
||||
"content": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
)";
|
||||
Json::Value result = compile(input);
|
||||
BOOST_CHECK(containsError(result, "JSONError",
|
||||
"Invalid checksum for library address \"0x42000000000000000000000000000000000000Ab\".\nThe correct checksum is \"0x42000000000000000000000000000000000000AB\"."));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(library_linking)
|
||||
|
Loading…
Reference in New Issue
Block a user