Skip to content

Commit

Permalink
Restrict contracts compiled via outputSelection (but not the individu…
Browse files Browse the repository at this point in the history
…al output details)
  • Loading branch information
axic committed Oct 4, 2017
1 parent f96e932 commit a0394a1
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 0 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Features:
* Parser: Better error message for unexpected trailing comma in parameter lists.
* Standard JSON: Support the ``outputSelection`` field for selective compilation of supplied sources.
* Syntax Checker: Unary ``+`` is now a syntax error as experimental 0.5.0 feature.
* Type Checker: Disallow non-pure constant state variables as experimental 0.5.0 feature.

Expand Down
19 changes: 19 additions & 0 deletions libsolidity/interface/StandardCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,22 @@ Json::Value formatErrorWithException(
return formatError(_warning, _type, _component, message, formattedMessage, location);
}

set<string> requestedContractNames(Json::Value const& _outputSelection)
{
set<string> names;
for (auto const& sourceName: _outputSelection.getMemberNames())
{
for (auto const& contractName: _outputSelection[sourceName].getMemberNames())
{
/// Consider the "all sources" shortcuts as requesting everything.
if (contractName == "*" || contractName == "")
return set<string>();
names.insert((sourceName == "*" ? "" : sourceName) + ":" + contractName);
}
}
return names;
}

/// Returns true iff @a _hash (hex with 0x prefix) is the Keccak256 hash of the binary data in @a _content.
bool hashMatchesContent(string const& _hash, string const& _content)
{
Expand Down Expand Up @@ -265,6 +281,9 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
Json::Value metadataSettings = settings.get("metadata", Json::Value());
m_compilerStack.useMetadataLiteralSources(metadataSettings.get("useLiteralContent", Json::Value(false)).asBool());

Json::Value outputSelection = settings.get("outputSelection", Json::Value());
m_compilerStack.setRequestedContractNames(requestedContractNames(outputSelection));

auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compilerStack.scanner(_sourceName); };

try
Expand Down
116 changes: 116 additions & 0 deletions test/libsolidity/StandardCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,122 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
);
}

BOOST_AUTO_TEST_CASE(output_selection_explicit)
{
char const* input = R"(
{
"language": "Solidity",
"settings": {
"outputSelection": {
"fileA": {
"A": [
"abi"
]
}
}
},
"sources": {
"fileA": {
"content": "contract A { }"
}
}
}
)";
Json::Value result = compile(input);
BOOST_CHECK(containsAtMostWarnings(result));
Json::Value contract = getContractResult(result, "fileA", "A");
BOOST_CHECK(contract.isObject());
BOOST_CHECK(contract["abi"].isArray());
BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[]");
}

BOOST_AUTO_TEST_CASE(output_selection_all_contracts)
{
char const* input = R"(
{
"language": "Solidity",
"settings": {
"outputSelection": {
"fileA": {
"*": [
"abi"
]
}
}
},
"sources": {
"fileA": {
"content": "contract A { }"
}
}
}
)";
Json::Value result = compile(input);
BOOST_CHECK(containsAtMostWarnings(result));
Json::Value contract = getContractResult(result, "fileA", "A");
BOOST_CHECK(contract.isObject());
BOOST_CHECK(contract["abi"].isArray());
BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[]");
}

BOOST_AUTO_TEST_CASE(output_selection_all_files_single_contract)
{
char const* input = R"(
{
"language": "Solidity",
"settings": {
"outputSelection": {
"*": {
"A": [
"abi"
]
}
}
},
"sources": {
"fileA": {
"content": "contract A { }"
}
}
}
)";
Json::Value result = compile(input);
BOOST_CHECK(containsAtMostWarnings(result));
Json::Value contract = getContractResult(result, "fileA", "A");
BOOST_CHECK(contract.isObject());
BOOST_CHECK(contract["abi"].isArray());
BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[]");
}

BOOST_AUTO_TEST_CASE(output_selection_all_files_all_contracts)
{
char const* input = R"(
{
"language": "Solidity",
"settings": {
"outputSelection": {
"*": {
"*": [
"abi"
]
}
}
},
"sources": {
"fileA": {
"content": "contract A { }"
}
}
}
)";
Json::Value result = compile(input);
BOOST_CHECK(containsAtMostWarnings(result));
Json::Value contract = getContractResult(result, "fileA", "A");
BOOST_CHECK(contract.isObject());
BOOST_CHECK(contract["abi"].isArray());
BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[]");
}

BOOST_AUTO_TEST_SUITE_END()

}
Expand Down

0 comments on commit a0394a1

Please sign in to comment.