mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11888 from ethereum/spdx-license-handling-10145
Properly detect multiple licenses and validate them.
This commit is contained in:
commit
4284499180
@ -22,6 +22,7 @@ Bugfixes:
|
||||
* Commandline Interface: Disallow the ``--experimental-via-ir`` option in Standard JSON, Assembler and Linker modes.
|
||||
* Opcode Optimizer: Prevent the optimizer from running multiple times to avoid potential bytecode differences for referenced code.
|
||||
* Name Resolver: Fix that when importing an aliased symbol using ``import {AliasedName} from "a.sol"`` it would use the original name of the symbol and not the aliased one.
|
||||
* Parser: Properly check for multiple SPDX license identifiers next to each other and validate them.
|
||||
* SMTChecker: Fix false negative caused by ``push`` on storage array references returned by internal functions.
|
||||
* SMTChecker: Fix false positive in external calls from constructors.
|
||||
* SMTChecker: Fix internal error on some multi-source uses of ``abi.*``, cryptographic functions and constants.
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <libyul/backends/evm/EVMDialect.h>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <cctype>
|
||||
#include <vector>
|
||||
#include <regex>
|
||||
@ -2078,7 +2079,8 @@ bool Parser::variableDeclarationStart()
|
||||
optional<string> Parser::findLicenseString(std::vector<ASTPointer<ASTNode>> const& _nodes)
|
||||
{
|
||||
// We circumvent the scanner here, because it skips non-docstring comments.
|
||||
static regex const licenseRegex("SPDX-License-Identifier:\\s*([a-zA-Z0-9 ()+.-]+)");
|
||||
static regex const licenseNameRegex("([a-zA-Z0-9 ()+.-]+)");
|
||||
static regex const licenseDeclarationRegex("SPDX-License-Identifier:\\s*(.+?)([\n\r]|(\\*/))");
|
||||
|
||||
// Search inside all parts of the source not covered by parsed nodes.
|
||||
// This will leave e.g. "global comments".
|
||||
@ -2093,21 +2095,33 @@ optional<string> Parser::findLicenseString(std::vector<ASTPointer<ASTNode>> cons
|
||||
sequencesToSearch.emplace_back(source.begin() + node->location().end, source.end());
|
||||
}
|
||||
|
||||
vector<string> matches;
|
||||
vector<string> licenseNames;
|
||||
for (auto const& [start, end]: sequencesToSearch)
|
||||
{
|
||||
smatch match;
|
||||
if (regex_search(start, end, match, licenseRegex))
|
||||
{
|
||||
string license{boost::trim_copy(string(match[1]))};
|
||||
if (!license.empty())
|
||||
matches.emplace_back(std::move(license));
|
||||
}
|
||||
auto declarationsBegin = std::sregex_iterator(start, end, licenseDeclarationRegex);
|
||||
auto declarationsEnd = std::sregex_iterator();
|
||||
|
||||
for (std::sregex_iterator declIt = declarationsBegin; declIt != declarationsEnd; ++declIt)
|
||||
if (!declIt->empty())
|
||||
{
|
||||
string license = boost::trim_copy(string((*declIt)[1]));
|
||||
licenseNames.emplace_back(std::move(license));
|
||||
}
|
||||
}
|
||||
|
||||
if (matches.size() == 1)
|
||||
return matches.front();
|
||||
else if (matches.empty())
|
||||
if (licenseNames.size() == 1)
|
||||
{
|
||||
string const& license = licenseNames.front();
|
||||
if (regex_match(license, licenseNameRegex))
|
||||
return license;
|
||||
else
|
||||
parserError(
|
||||
1114_error,
|
||||
{-1, -1, m_scanner->currentLocation().sourceName},
|
||||
"Invalid SPDX license identifier."
|
||||
);
|
||||
}
|
||||
else if (licenseNames.empty())
|
||||
parserWarning(
|
||||
1878_error,
|
||||
{-1, -1, m_scanner->currentLocation().sourceName},
|
||||
|
@ -120,7 +120,11 @@ done < <(
|
||||
# a variable declaration.
|
||||
grep -v -E 'revertStatement/non_called.sol' |
|
||||
# Skipping a test with "let basefee := ..."
|
||||
grep -v -E 'inlineAssembly/basefee_berlin_function.sol'
|
||||
grep -v -E 'inlineAssembly/basefee_berlin_function.sol' |
|
||||
# Skipping license error, unrelated to the grammar
|
||||
grep -v -E 'license/license_double5.sol' |
|
||||
grep -v -E 'license/license_hidden_unicode.sol' |
|
||||
grep -v -E 'license/license_unicode.sol'
|
||||
)
|
||||
|
||||
YUL_FILES=()
|
||||
|
@ -457,28 +457,6 @@ BOOST_AUTO_TEST_CASE(metadata_license_gpl3_or_apache2)
|
||||
BOOST_CHECK(compileAndCheckLicenseMetadata("C", sourceCode) == "GPL-3.0 OR Apache-2.0");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(metadata_license_ignored_unicode)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
// SPDX-License-Identifier: ⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒
|
||||
pragma solidity >=0.0;
|
||||
contract C {
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK(compileAndCheckLicenseMetadata("C", sourceCode) == nullopt);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(metadata_license_ignored_stray_unicode)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
// SPDX-License-Identifier: GPL-3.0 ⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒
|
||||
pragma solidity >=0.0;
|
||||
contract C {
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK(compileAndCheckLicenseMetadata("C", sourceCode) == "GPL-3.0");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(metadata_license_bidi_marks)
|
||||
{
|
||||
char const* sourceCode =
|
||||
@ -570,15 +548,6 @@ BOOST_AUTO_TEST_CASE(metadata_license_natspec_multiline)
|
||||
BOOST_CHECK(compileAndCheckLicenseMetadata("C", sourceCode) == "GPL-3.0");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(metadata_license_no_whitespace)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
//SPDX-License-Identifier:GPL-3.0
|
||||
contract C {}
|
||||
)";
|
||||
BOOST_CHECK(compileAndCheckLicenseMetadata("C", sourceCode) == "GPL-3.0");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(metadata_license_no_whitespace_multiline)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@ -597,6 +566,15 @@ BOOST_AUTO_TEST_CASE(metadata_license_nonempty_line)
|
||||
BOOST_CHECK(compileAndCheckLicenseMetadata("C", sourceCode) == "GPL-3.0");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(metadata_license_no_whitespace)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
//SPDX-License-Identifier:GPL-3.0
|
||||
contract C {}
|
||||
)";
|
||||
BOOST_CHECK(compileAndCheckLicenseMetadata("C", sourceCode) == "GPL-3.0");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
3
test/libsolidity/syntaxTests/license/license_AND.sol
Normal file
3
test/libsolidity/syntaxTests/license/license_AND.sol
Normal file
@ -0,0 +1,3 @@
|
||||
// SPDX-License-Identifier: GPL-3.0 AND GPL-2.0
|
||||
contract C {}
|
||||
// ----
|
3
test/libsolidity/syntaxTests/license/license_OR.sol
Normal file
3
test/libsolidity/syntaxTests/license/license_OR.sol
Normal file
@ -0,0 +1,3 @@
|
||||
// SPDX-License-Identifier: GPL-3.0 OR GPL-2.0
|
||||
contract C {}
|
||||
// ----
|
5
test/libsolidity/syntaxTests/license/license_double2.sol
Normal file
5
test/libsolidity/syntaxTests/license/license_double2.sol
Normal file
@ -0,0 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
contract C {}
|
||||
// ----
|
||||
// ParserError 3716: Multiple SPDX license identifiers found in source file. Use "AND" or "OR" to combine multiple licenses. Please see https://spdx.org for more information.
|
5
test/libsolidity/syntaxTests/license/license_double3.sol
Normal file
5
test/libsolidity/syntaxTests/license/license_double3.sol
Normal file
@ -0,0 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
contract C {}
|
||||
// ----
|
||||
// ParserError 3716: Multiple SPDX license identifiers found in source file. Use "AND" or "OR" to combine multiple licenses. Please see https://spdx.org for more information.
|
5
test/libsolidity/syntaxTests/license/license_double4.sol
Normal file
5
test/libsolidity/syntaxTests/license/license_double4.sol
Normal file
@ -0,0 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0 OR GPL-2.0
|
||||
SPDX-License-Identifier: GPL-3.0 OR GPL-2.0 */
|
||||
contract C {}
|
||||
// ----
|
||||
// ParserError 3716: Multiple SPDX license identifiers found in source file. Use "AND" or "OR" to combine multiple licenses. Please see https://spdx.org for more information.
|
4
test/libsolidity/syntaxTests/license/license_double5.sol
Normal file
4
test/libsolidity/syntaxTests/license/license_double5.sol
Normal file
@ -0,0 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0 OR GPL-2.0 */ /* SPDX-License-Identifier: GPL-3.0 OR GPL-2.0 */
|
||||
contract C {}
|
||||
// ----
|
||||
// ParserError 3716: Multiple SPDX license identifiers found in source file. Use "AND" or "OR" to combine multiple licenses. Please see https://spdx.org for more information.
|
@ -1,4 +1,4 @@
|
||||
// This is parsed as GPL-3.0:
|
||||
// SPDX-License-Identifier: GPL-3.0 ⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒
|
||||
contract C {}
|
||||
// ----
|
||||
// ParserError 1114: Invalid SPDX license identifier.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: ⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒
|
||||
contract C {}
|
||||
// ----
|
||||
// Warning 1878: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
|
||||
// ParserError 1114: Invalid SPDX license identifier.
|
||||
|
Loading…
Reference in New Issue
Block a user