11/** Provides classes and predicates related to handling APIs from external libraries. */
22
33private import java
4- private import APIUsage
4+ private import semmle.code.java.dataflow.DataFlow
5+ private import semmle.code.java.dataflow.DataFlow
56private import semmle.code.java.dataflow.ExternalFlow
7+ private import semmle.code.java.dataflow.FlowSources
8+ private import semmle.code.java.dataflow.FlowSummary
9+ private import semmle.code.java.dataflow.internal.DataFlowPrivate
10+ private import semmle.code.java.dataflow.TaintTracking
611
712/**
813 * An external API from either the Java Standard Library or a 3rd party library.
914 */
1015class ExternalAPI extends Callable {
1116 ExternalAPI ( ) { not this .fromSource ( ) }
1217
18+ /** Holds if this API is a candidate worth supporting */
19+ predicate isWorthSupporting ( ) { not isTestLibrary ( ) and not isParameterlessConstructor ( ) }
20+
21+ /** Holds if this API is is a constructor without parameters */
22+ predicate isParameterlessConstructor ( ) {
23+ this instanceof Constructor and this .getNumberOfParameters ( ) = 0
24+ }
25+
1326 /** Holds if this API is part of a common testing library or framework */
14- predicate isTestLibrary ( ) { getDeclaringType ( ) instanceof TestLibrary }
27+ private predicate isTestLibrary ( ) { getDeclaringType ( ) instanceof TestLibrary }
1528
1629 /**
1730 * Gets information about the external API in the form expected by the CSV modeling framework.
@@ -22,9 +35,6 @@ class ExternalAPI extends Callable {
2235 "#" + api .getName ( ) + paramsString ( api )
2336 }
2437
25- /** Holds if this API is not yet supported by existing CodeQL libraries */
26- predicate isSupported ( ) { not supportKind ( this ) = "?" }
27-
2838 /**
2939 * Gets the jar file containing this API. Normalizes the Java Runtime to "rt.jar" despite the presence of modules.
3040 */
@@ -33,6 +43,39 @@ class ExternalAPI extends Callable {
3343 private string containerAsJar ( Container container ) {
3444 if container instanceof JarFile then result = container .getBaseName ( ) else result = "rt.jar"
3545 }
46+
47+ /** Gets a node that is an input to a call to this API. */
48+ private DataFlow:: Node getAnInput ( ) {
49+ exists ( Call call | call .getCallee ( ) .getSourceDeclaration ( ) = this |
50+ result .asExpr ( ) .( Argument ) .getCall ( ) = call or
51+ result .( ArgumentNode ) .getCall ( ) = call
52+ )
53+ }
54+
55+ /** Gets a node that is an output from a call to this API. */
56+ private DataFlow:: Node getAnOutput ( ) {
57+ exists ( Call call | call .getCallee ( ) .getSourceDeclaration ( ) = this |
58+ result .asExpr ( ) = call or
59+ result .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) .( ArgumentNode ) .getCall ( ) = call
60+ )
61+ }
62+
63+ /** Holds if this API has a supported summary. */
64+ predicate hasSummary ( ) {
65+ this instanceof SummarizedCallable or
66+ TaintTracking:: localAdditionalTaintStep ( this .getAnInput ( ) , _)
67+ }
68+
69+ /** Holds if this API is a known source. */
70+ predicate isSource ( ) {
71+ this .getAnOutput ( ) instanceof RemoteFlowSource or sourceNode ( this .getAnOutput ( ) , _)
72+ }
73+
74+ /** Holds if this API is a known sink. */
75+ predicate isSink ( ) { sinkNode ( this .getAnInput ( ) , _) }
76+
77+ /** Holds if this API is supported by existing CodeQL libraries, that is, it is either a recognized source or sink or has a flow summary. */
78+ predicate isSupported ( ) { hasSummary ( ) or isSource ( ) or isSink ( ) }
3679}
3780
3881private class TestLibrary extends RefType {
0 commit comments