Merge pull request #13823 from github/kaeluka/support-argument-this-in-frameworkmode-metadata-extraction

Java: Support Argument[this] and parameters of bodiless interface methods in framework mode metadata extraction
This commit is contained in:
Stephan Brandauer 2023-07-28 17:38:39 +02:00 коммит произвёл GitHub
Родитель 08cba7dc5f 8bf960bd44
Коммит 40eab180cc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 69 добавлений и 16 удалений

Просмотреть файл

@ -23,6 +23,64 @@ newtype JavaRelatedLocationType =
MethodDoc() or
ClassDoc()
newtype TFrameworkModeEndpoint =
TExplicitParameter(Parameter p) or
TQualifier(Callable c)
/**
* A framework mode endpoint.
*/
abstract class FrameworkModeEndpoint extends TFrameworkModeEndpoint {
/**
* Returns the parameter index of the endpoint.
*/
abstract int getIndex();
/**
* Returns the name of the parameter of the endpoint.
*/
abstract string getParamName();
/**
* Returns the callable that contains the endpoint.
*/
abstract Callable getEnclosingCallable();
abstract Top asTop();
string toString() { result = this.asTop().toString() }
Location getLocation() { result = this.asTop().getLocation() }
}
class ExplicitParameterEndpoint extends FrameworkModeEndpoint, TExplicitParameter {
Parameter param;
ExplicitParameterEndpoint() { this = TExplicitParameter(param) }
override int getIndex() { result = param.getPosition() }
override string getParamName() { result = param.getName() }
override Callable getEnclosingCallable() { result = param.getCallable() }
override Top asTop() { result = param }
}
class QualifierEndpoint extends FrameworkModeEndpoint, TQualifier {
Callable callable;
QualifierEndpoint() { this = TQualifier(callable) }
override int getIndex() { result = -1 }
override string getParamName() { result = "this" }
override Callable getEnclosingCallable() { result = callable }
override Top asTop() { result = callable }
}
/**
* A candidates implementation for framework mode.
*
@ -33,7 +91,7 @@ newtype JavaRelatedLocationType =
*/
module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
// for documentation of the implementations here, see the QLDoc in the CandidateSig signature module.
class Endpoint = DataFlow::ParameterNode;
class Endpoint = FrameworkModeEndpoint;
class EndpointType = AutomodelEndpointTypes::EndpointType;
@ -46,7 +104,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
// Sanitizers are currently not modeled in MaD. TODO: check if this has large negative impact.
predicate isSanitizer(Endpoint e, EndpointType t) { none() }
RelatedLocation asLocation(Endpoint e) { result = e.asParameter() }
RelatedLocation asLocation(Endpoint e) { result = e.asTop() }
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2;
@ -70,9 +128,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
FrameworkModeGetCallable::getCallable(e).hasQualifiedName(package, type, name) and
signature = ExternalFlow::paramsString(FrameworkModeGetCallable::getCallable(e)) and
ext = "" and
exists(int paramIdx | e.isParameterOf(_, paramIdx) |
input = AutomodelJavaUtil::getArgumentForIndex(paramIdx)
)
input = AutomodelJavaUtil::getArgumentForIndex(e.getIndex())
}
/**
@ -124,16 +180,13 @@ class FrameworkModeMetadataExtractor extends string {
Endpoint e, string package, string type, string subtypes, string name, string signature,
string input, string parameterName
) {
exists(Callable callable, int paramIdx |
e.asParameter() = callable.getParameter(paramIdx) and
input = AutomodelJavaUtil::getArgumentForIndex(paramIdx) and
package = callable.getDeclaringType().getPackage().getName() and
type = callable.getDeclaringType().getErasure().(RefType).nestedName() and
subtypes = AutomodelJavaUtil::considerSubtypes(callable).toString() and
name = callable.getName() and
parameterName = e.asParameter().getName() and
signature = ExternalFlow::paramsString(callable)
)
parameterName = e.getParamName() and
name = e.getEnclosingCallable().getName() and
input = AutomodelJavaUtil::getArgumentForIndex(e.getIndex()) and
package = e.getEnclosingCallable().getDeclaringType().getPackage().getName() and
type = e.getEnclosingCallable().getDeclaringType().getErasure().(RefType).nestedName() and
subtypes = AutomodelJavaUtil::considerSubtypes(e.getEnclosingCallable()).toString() and
signature = ExternalFlow::paramsString(e.getEnclosingCallable())
}
}
@ -201,7 +254,7 @@ private class NotAModelApiParameter extends CharacteristicsImpl::UninterestingTo
NotAModelApiParameter() { this = "not a model API parameter" }
override predicate appliesToEndpoint(Endpoint e) {
not exists(ModelExclusions::ModelApi api | api.getAParameter() = e.asParameter())
not e.getEnclosingCallable() instanceof ModelExclusions::ModelApi
}
}