distlib/luigi/zookeeper/mybatis/solc/solana/go-ethereum: CWE-407 patches + unit tests; solana CLEAN

This commit is contained in:
russell@unturf.com 2026-03-30 07:06:26 -04:00
parent c9e86c450c
commit b4e2eda927
17 changed files with 2087 additions and 1 deletions

View file

@ -0,0 +1,45 @@
# solc-0002 — ContractLevelChecker findDuplicateDefinitions — CLEAN (CWE-407)
## File
`libsolidity/analysis/ContractLevelChecker.cpp` ~line 239
## Pattern reviewed
```cpp
std::set<size_t> reported;
for (size_t i = 0; i < overloads.size() && !reported.count(i); ++i)
```
## CWE-407 verdict: NOT a performance defect
`std::set<size_t>::count` is O(log N), making the loop O(N log N) — well within
acceptable complexity for the use case. N is bounded by the number of overloaded
definitions of a single name in a contract, which in practice is tiny (< 20).
No CWE-407 patch warranted.
## Separate logic concern (not CWE-407)
The `!reported.count(i)` loop guard has a latent correctness defect: if index `i`
was inserted into `reported` as a *duplicate* during an earlier outer iteration
(e.g., iteration i=0 found j=2 is a duplicate and inserted 2), then when the outer
loop reaches i=2 the guard fires and the loop exits early. This causes i=2 to be
silently skipped as a *primary* candidate, potentially missing further duplicates
whose first occurrence is at index 2.
This is a correctness/logic defect, not a CWE-407 algorithmic-complexity defect.
It should be tracked separately if it produces missed duplicate-definition errors
in practice.
## Recommendation
Change the loop guard to allow all `i` to be visited as primary candidates:
```cpp
for (size_t i = 0; i < overloads.size(); ++i)
{
if (reported.count(i)) continue; // already flagged as someone else's dup
...
}
```
This preserves the intent (skip reporting i if it was already reported as a
duplicate of an earlier declaration) while not prematurely terminating the loop.

View file

@ -0,0 +1,61 @@
# UNDF: UNDF-2026-000000288
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -3611,9 +3611,17 @@ std::vector<Declaration const*> TypeChecker::cleanOverloadedDeclarations(
Identifier const& _identifier,
std::vector<Declaration const*> const& _candidates
)
{
solAssert(_candidates.size() > 1, "");
+
+ // CWE-407 fix: use a set keyed by canonical parameter-type string to avoid
+ // the O(N²) find_if scan. For each incoming declaration we resolve its
+ // FunctionType once, serialise the parameter+return types into a string key,
+ // and do an O(1) unordered_set probe instead of a linear walk over
+ // uniqueDeclarations. The original code called declaration->functionType()
+ // twice (false then true) inside an inner lambda that was invoked once per
+ // already-accumulated unique entry — O(N²) function-type resolutions in the
+ // worst case where every declaration has a distinct signature.
std::vector<Declaration const*> uniqueDeclarations;
+ std::unordered_set<std::string> seenSignatures;
for (Declaration const* declaration: _candidates)
{
@@ -3631,15 +3639,17 @@ std::vector<Declaration const*> TypeChecker::cleanOverloadedDeclarations(
FunctionTypePointer functionType {declaration->functionType(false)};
if (!functionType)
functionType = declaration->functionType(true);
solAssert(functionType, "Failed to determine the function type of the overloaded.");
for (Type const* parameter: functionType->parameterTypes() + functionType->returnParameterTypes())
if (!parameter)
m_errorReporter.fatalDeclarationError(3893_error, _identifier.location(), "Function type can not be used in this context.");
- if (uniqueDeclarations.end() == find_if(
- uniqueDeclarations.begin(),
- uniqueDeclarations.end(),
- [&](Declaration const* d)
- {
- FunctionType const* newFunctionType = d->functionType(false);
- if (!newFunctionType)
- newFunctionType = d->functionType(true);
- return newFunctionType && functionType->hasEqualParameterTypes(*newFunctionType);
- }
- ))
+ // Build a canonical signature key from parameter and return types.
+ // Two declarations are considered duplicates iff their parameter types
+ // are equal (hasEqualParameterTypes), so we key on the human-readable
+ // parameter-type string which FunctionType already exposes via
+ // toString(false) on each parameter. This gives O(1) duplicate
+ // detection instead of the prior O(N) find_if per candidate.
+ std::string sigKey;
+ for (Type const* p : functionType->parameterTypes())
+ sigKey += p->toString(false) + ",";
+ sigKey += "|";
+ for (Type const* r : functionType->returnParameterTypes())
+ sigKey += r->toString(false) + ",";
+
+ if (seenSignatures.insert(sigKey).second)
uniqueDeclarations.push_back(declaration);
}
return uniqueDeclarations;