Merge pull request #13860 from ethereum/forbid_private_library_functions_attached

Forbid private library functions be attached with using for outside their declaration scope
This commit is contained in:
Kamil Śliwak 2023-01-17 22:11:29 +01:00 committed by GitHub
commit 96ddc54fa2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 0 deletions

View File

@ -30,6 +30,7 @@ Bugfixes:
* SMTChecker: Fix internal error on chain assignments using static fully specified state variables.
* SMTChecker: Fix internal error when using user defined types as mapping indices or struct members.
* SMTChecker: Fix internal error when deleting struct member of function type.
* TypeChecker: Fix bug where private library functions could be attached with ``using for`` outside of their declaration scope.
### 0.8.17 (2022-09-08)

View File

@ -3809,6 +3809,10 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
m_errorReporter.fatalTypeError(
4731_error,
path->location(),
SecondarySourceLocation().append(
"Function defined here:",
functionDefinition.location()
),
fmt::format(
"The function \"{}\" does not have any parameters, and therefore cannot be attached to the type \"{}\".",
joinHumanReadable(path->path(), "."),
@ -3816,6 +3820,27 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
)
);
if (
functionDefinition.visibility() == Visibility::Private &&
functionDefinition.scope() != m_currentContract
)
{
solAssert(functionDefinition.libraryFunction());
m_errorReporter.typeError(
6772_error,
path->location(),
SecondarySourceLocation().append(
"Function defined here:",
functionDefinition.location()
),
fmt::format(
"Function \"{}\" is private and therefore cannot be attached"
" to a type outside of the library where it is defined.",
joinHumanReadable(path->path(), ".")
)
);
}
FunctionType const* functionType = dynamic_cast<FunctionType const&>(*functionDefinition.type()).withBoundFirstArgument();
solAssert(functionType && functionType->selfType(), "");
BoolResult result = normalizedType->isImplicitlyConvertibleTo(

View File

@ -0,0 +1,10 @@
library L {
using {L.privateFunction} for uint;
function privateFunction(uint x) private pure returns (uint) { return x + 1; }
function f() public pure returns (uint) {
uint x = 1;
return x.privateFunction();
}
}
// ----
// f() -> 2

View File

@ -0,0 +1,5 @@
library L {
using {L.privateFunction} for uint;
function privateFunction(uint) private pure {}
}
// ----

View File

@ -0,0 +1,12 @@
library L {
function privateFunction(uint) private pure {}
}
using {L.privateFunction} for uint;
contract C {
using {L.privateFunction} for uint;
}
// ----
// TypeError 6772: (73-90): Function "L.privateFunction" is private and therefore cannot be attached to a type outside of the library where it is defined.
// TypeError 6772: (127-144): Function "L.privateFunction" is private and therefore cannot be attached to a type outside of the library where it is defined.