Merge branch 'main' into atorralba/android_slice_models

This commit is contained in:
Tony Torralba
2021-12-03 16:59:33 +01:00
committed by GitHub
2090 changed files with 231632 additions and 37666 deletions

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Add support for [Ratpack](https://ratpack.io/) HTTP framework.

View File

@@ -0,0 +1,5 @@
lgtm,codescanning
* A new query "Android Intent redirection" (`java/android/intent-redirection`) has been added.
This query finds exported Android components using received Intents to start other components,
which can provide access to internal components of the application or cause other unintended
effects.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The query "Leaking sensitive information through an implicit Intent" (`java/android/sensitive-communication`) has been promoted from experimental to the main query pack. Its results will now appear by default. The query was originally [submitted as an experimental query by @luchua-bc.](https://github.com/github/codeql/pull/4512)

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Some uses of `RefType` in the support for 'generics' and 'imports' now use the more specific `ClassOrInterface` instead

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The predicate `StringLiteral.getRepresentedString()` has been deprecated for removal in a future version because it is just an alias for `getValue()`. That predicate should be used instead.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Added data flow models for lambda methods on `java.util.Optional`.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The predicate `Method.overrides(Method)` was accidentally transitive. This has been fixed. This fix also affects `Method.overridesOrInstantiates(Method)` and `Method.getASourceOverriddenMethod()`.

View File

@@ -0,0 +1,3 @@
lgtm,codescanning
* `CharacterLiteral`'s `getCodePointValue` predicate now returns the correct value for UTF-16 surrogates.
* The `RangeAnalysis` module and the `java/constant-comparison` queries no longer raise false alerts regarding comparisons with Unicode surrogate character literals.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Improved support for the [Ratpack](https://ratpack.io/) HTTP framework: added data-flow models of `ratpack.func.Pair` and `ratpack.exec.Result`, and improved models of `ratpack.exec.Promise`.

View File

@@ -1,92 +1,102 @@
package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:jexl,sink:jndi-injection,sink:ldap,sink:mvel,sink:ognl-injection,sink:open-url,sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:xpath,sink:xslt,sink:xss,source:contentprovider,source:remote,summary:taint,summary:value
android.content,8,27,73,,,,,,,,,,,,,8,,,,,,27,,8,65
android.database,59,,30,,,,,,,,,,,,,59,,,,,,,,30,
android.net,,,60,,,,,,,,,,,,,,,,,,,,,45,15
android.os,,,122,,,,,,,,,,,,,,,,,,,,,41,81
android.util,,16,,,,,,,,,,,,,,,,,,,,,16,,
android.webkit,3,2,,,,,,,,,,,,,,,,,,,3,,2,,
cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,1,
com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,1,
com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,1,
com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,1,
com.fasterxml.jackson.databind,,,5,,,,,,,,,,,,,,,,,,,,,5,
com.google.common.base,,,85,,,,,,,,,,,,,,,,,,,,,62,23
com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,17
com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,2,551
com.google.common.io,6,,73,,,,,,,,,,,,,,6,,,,,,,72,1
com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,3,,,,,,,,,,,,
com.unboundid.ldap.sdk,17,,,,,,,,,,17,,,,,,,,,,,,,,
flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,1
groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,
groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,
jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,2,,7,,
jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,100,23
jakarta.ws.rs.client,1,,,,,,,,,,,,,1,,,,,,,,,,,
jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,9,,
jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,2,,,,,,94,55
java.beans,,,1,,,,,,,,,,,,,,,,,,,,,1,
java.io,3,,27,,3,,,,,,,,,,,,,,,,,,,26,1
java.lang,,,50,,,,,,,,,,,,,,,,,,,,,41,9
java.net,10,3,7,,,,,,,,,,,10,,,,,,,,,3,7,
java.nio,10,,4,,10,,,,,,,,,,,,,,,,,,,4,
java.sql,7,,,,,,,,,,,,,,,7,,,,,,,,,
java.util,,,417,,,,,,,,,,,,,,,,,,,,,15,402
javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,2,,7,,
javax.json,,,123,,,,,,,,,,,,,,,,,,,,,100,23
javax.management.remote,2,,,,,,,,,2,,,,,,,,,,,,,,,
javax.naming,7,,,,,,,,,6,1,,,,,,,,,,,,,,
javax.net.ssl,2,,,,,,,,,,,,,,2,,,,,,,,,,
javax.script,1,,,,,,,,,,,1,,,,,,,,,,,,,
javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,21,2,
javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,1,,
javax.ws.rs.client,1,,,,,,,,,,,,,1,,,,,,,,,,,
javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,9,,
javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,2,,,,,,94,55
javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,1,,,,6,
javax.xml.xpath,3,,,,,,,,,,,,,,,,,,3,,,,,,
jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,10
net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,5,,,,,
ognl,6,,,,,,,,,,,,6,,,,,,,,,,,,
org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,6,
org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,17,783
org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,17,783
org.apache.commons.io,,,22,,,,,,,,,,,,,,,,,,,,,22,
org.apache.commons.jexl2,15,,,,,,,,15,,,,,,,,,,,,,,,,
org.apache.commons.jexl3,15,,,,,,,,15,,,,,,,,,,,,,,,,
org.apache.commons.lang3,,,423,,,,,,,,,,,,,,,,,,,,,292,131
org.apache.commons.ognl,6,,,,,,,,,,,,6,,,,,,,,,,,,
org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,220,52
org.apache.directory.ldap.client.api,1,,,,,,,,,,1,,,,,,,,,,,,,,
org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,1,
org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,1,,2,39,
org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,2,
org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,18,6
org.apache.http,27,3,70,,,,,,,,,,,25,,,,,,,2,,3,62,8
org.apache.ibatis.jdbc,6,,,,,,,,,,,,,,,6,,,,,,,,,
org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,1,
org.apache.shiro.jndi,1,,,,,,,,,1,,,,,,,,,,,,,,,
org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,
org.dom4j,20,,,,,,,,,,,,,,,,,,20,,,,,,
org.hibernate,7,,,,,,,,,,,,,,,7,,,,,,,,,
org.jooq,1,,,,,,,,,,,,,,,1,,,,,,,,,
org.json,,,236,,,,,,,,,,,,,,,,,,,,,198,38
org.mvel2,16,,,,,,,,,,,16,,,,,,,,,,,,,
org.springframework.beans,,,26,,,,,,,,,,,,,,,,,,,,,,26
org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,13
org.springframework.http,14,,70,,,,,,,,,,,14,,,,,,,,,,60,10
org.springframework.jdbc.core,10,,,,,,,,,,,,,,,10,,,,,,,,,
org.springframework.jdbc.object,9,,,,,,,,,,,,,,,9,,,,,,,,,
org.springframework.jndi,1,,,,,,,,,1,,,,,,,,,,,,,,,
org.springframework.ldap,42,,,,,,,,,28,14,,,,,,,,,,,,,,
org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,6,,
org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,32
org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,87,52
org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,13,
org.springframework.web.client,13,3,,,,,,,,,,,,13,,,,,,,,,3,,
org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,8,,
org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,12,13,
org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,2,,,,,,,,,,,
org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,138,25
org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,1,
org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,3,,
play.mvc,,4,,,,,,,,,,,,,,,,,,,,,4,,
package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jexl,sink:jndi-injection,sink:ldap,sink:mvel,sink:ognl-injection,sink:open-url,sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:xpath,sink:xslt,sink:xss,source:contentprovider,source:remote,summary:taint,summary:value
android.app,7,,,,,,,,7,,,,,,,,,,,,,,,,,
android.content,24,27,96,,,,,,16,,,,,,,,8,,,,,,27,,31,65
android.database,59,,30,,,,,,,,,,,,,,59,,,,,,,,30,
android.net,,,60,,,,,,,,,,,,,,,,,,,,,,45,15
android.os,,,122,,,,,,,,,,,,,,,,,,,,,,41,81
android.util,,16,,,,,,,,,,,,,,,,,,,,,,16,,
android.webkit,3,2,,,,,,,,,,,,,,,,,,,,3,,2,,
cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,1,
com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,1,
com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,1,
com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,1,
com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,6,
com.google.common.base,,,85,,,,,,,,,,,,,,,,,,,,,,62,23
com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,17
com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,2,551
com.google.common.io,6,,73,,,,,,,,,,,,,,,6,,,,,,,72,1
com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,3,,,,,,,,,,,,
com.unboundid.ldap.sdk,17,,,,,,,,,,,17,,,,,,,,,,,,,,
flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,1
groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,
groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,
jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,2,,7,,
jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,100,23
jakarta.ws.rs.client,1,,,,,,,,,,,,,,1,,,,,,,,,,,
jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,9,,
jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,2,,,,,,94,55
java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,1,
java.io,3,,31,,3,,,,,,,,,,,,,,,,,,,,30,1
java.lang,,,52,,,,,,,,,,,,,,,,,,,,,,42,10
java.net,10,3,7,,,,,,,,,,,,10,,,,,,,,,3,7,
java.nio,10,,4,,10,,,,,,,,,,,,,,,,,,,,4,
java.sql,7,,,,,,,,,,,,,,,,7,,,,,,,,,
java.util,,,429,,,,,,,,,,,,,,,,,,,,,,15,414
javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,2,,7,,
javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,100,23
javax.management.remote,2,,,,,,,,,,2,,,,,,,,,,,,,,,
javax.naming,7,,,,,,,,,,6,1,,,,,,,,,,,,,,
javax.net.ssl,2,,,,,,,,,,,,,,,2,,,,,,,,,,
javax.script,1,,,,,,,,,,,,1,,,,,,,,,,,,,
javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,21,2,
javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,1,,
javax.ws.rs.client,1,,,,,,,,,,,,,,1,,,,,,,,,,,
javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,9,,
javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,2,,,,,,94,55
javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,1,,,,6,
javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,3,,,,,,
jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,10
net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,5,,,,,
ognl,6,,,,,,,,,,,,,6,,,,,,,,,,,,
org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,6,
org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,17,783
org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,17,783
org.apache.commons.io,,,22,,,,,,,,,,,,,,,,,,,,,,22,
org.apache.commons.jexl2,15,,,,,,,,,15,,,,,,,,,,,,,,,,
org.apache.commons.jexl3,15,,,,,,,,,15,,,,,,,,,,,,,,,,
org.apache.commons.lang3,,,423,,,,,,,,,,,,,,,,,,,,,,292,131
org.apache.commons.ognl,6,,,,,,,,,,,,,6,,,,,,,,,,,,
org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,220,52
org.apache.directory.ldap.client.api,1,,,,,,,,,,,1,,,,,,,,,,,,,,
org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,1,
org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,1,,2,39,
org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,2,
org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,18,6
org.apache.http,27,3,70,,,,,,,,,,,,25,,,,,,,2,,3,62,8
org.apache.ibatis.jdbc,6,,,,,,,,,,,,,,,,6,,,,,,,,,
org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,1,
org.apache.shiro.jndi,1,,,,,,,,,,1,,,,,,,,,,,,,,,
org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,
org.dom4j,20,,,,,,,,,,,,,,,,,,,20,,,,,,
org.hibernate,7,,,,,,,,,,,,,,,,7,,,,,,,,,
org.jooq,1,,,,,,,,,,,,,,,,1,,,,,,,,,
org.json,,,236,,,,,,,,,,,,,,,,,,,,,,198,38
org.mvel2,16,,,,,,,,,,,,16,,,,,,,,,,,,,
org.springframework.beans,,,26,,,,,,,,,,,,,,,,,,,,,,,26
org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,13
org.springframework.http,14,,70,,,,,,,,,,,,14,,,,,,,,,,60,10
org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,10,,,,,,,,,
org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,9,,,,,,,,,
org.springframework.jndi,1,,,,,,,,,,1,,,,,,,,,,,,,,,
org.springframework.ldap,42,,,,,,,,,,28,14,,,,,,,,,,,,,,
org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,6,,
org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,32
org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,87,52
org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,13,
org.springframework.web.client,13,3,,,,,,,,,,,,,13,,,,,,,,,3,,
org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,8,,
org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,12,13,
org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,2,,,,,,,,,,,
org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,138,25
org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,1,
org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,3,,
play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,4,,
ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,3,
ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,6,4,
ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,10,10,
ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,48
ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,3,
ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,35
ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,6,4,
ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,10,10,
ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,35
1 package sink source summary sink:bean-validation sink:create-file sink:groovy sink:header-splitting sink:information-leak sink:intent-start sink:jexl sink:jndi-injection sink:ldap sink:mvel sink:ognl-injection sink:open-url sink:set-hostname-verifier sink:sql sink:url-open-stream sink:url-redirect sink:xpath sink:xslt sink:xss source:contentprovider source:remote summary:taint summary:value
2 android.content android.app 8 7 27 73 7 8 27 8 65
3 android.database android.content 59 24 27 30 96 16 59 8 27 30 31 65
4 android.net android.database 59 60 30 59 45 30 15
5 android.os android.net 122 60 41 45 81 15
6 android.util android.os 16 122 16 41 81
7 android.webkit android.util 3 2 16 3 2 16
8 cn.hutool.core.codec android.webkit 3 2 1 3 2 1
9 com.esotericsoftware.kryo.io cn.hutool.core.codec 1 1
10 com.esotericsoftware.kryo5.io com.esotericsoftware.kryo.io 1 1
11 com.fasterxml.jackson.core com.esotericsoftware.kryo5.io 1 1
12 com.fasterxml.jackson.databind com.fasterxml.jackson.core 5 1 5 1
13 com.google.common.base com.fasterxml.jackson.databind 85 6 62 6 23
14 com.google.common.cache com.google.common.base 17 85 62 17 23
15 com.google.common.collect com.google.common.cache 553 17 2 551 17
16 com.google.common.io com.google.common.collect 6 73 553 6 72 2 1 551
17 com.opensymphony.xwork2.ognl com.google.common.io 3 6 73 3 6 72 1
18 com.unboundid.ldap.sdk com.opensymphony.xwork2.ognl 17 3 17 3
19 flexjson com.unboundid.ldap.sdk 17 1 17 1
20 groovy.lang flexjson 26 1 26 1
21 groovy.util groovy.lang 5 26 5 26
22 jakarta.faces.context groovy.util 2 5 7 5 2 7
23 jakarta.json jakarta.faces.context 2 7 123 2 7 100 23
24 jakarta.ws.rs.client jakarta.json 1 123 1 100 23
25 jakarta.ws.rs.container jakarta.ws.rs.client 1 9 1 9
26 jakarta.ws.rs.core jakarta.ws.rs.container 2 9 149 2 9 94 55
27 java.beans jakarta.ws.rs.core 2 1 149 2 1 94 55
28 java.io java.beans 3 27 1 3 26 1 1
29 java.lang java.io 3 50 31 3 41 30 9 1
30 java.net java.lang 10 3 7 52 10 3 7 42 10
31 java.nio java.net 10 3 4 7 10 10 3 4 7
32 java.sql java.nio 7 10 4 10 7 4
33 java.util java.sql 7 417 7 15 402
34 javax.faces.context java.util 2 7 429 2 7 15 414
35 javax.json javax.faces.context 2 7 123 2 7 100 23
36 javax.management.remote javax.json 2 123 2 100 23
37 javax.naming javax.management.remote 7 2 6 2 1
38 javax.net.ssl javax.naming 2 7 6 1 2
39 javax.script javax.net.ssl 1 2 1 2
40 javax.servlet javax.script 4 1 21 2 3 1 1 21 2
41 javax.validation javax.servlet 1 4 1 21 2 1 3 1 1 21 2
42 javax.ws.rs.client javax.validation 1 1 1 1 1
43 javax.ws.rs.container javax.ws.rs.client 1 9 1 9
44 javax.ws.rs.core javax.ws.rs.container 3 9 149 1 2 9 94 55
45 javax.xml.transform javax.ws.rs.core 1 3 6 149 1 2 1 6 94 55
46 javax.xml.xpath javax.xml.transform 3 1 6 3 1 6
47 jodd.json javax.xml.xpath 3 10 3 10
48 net.sf.saxon.s9api jodd.json 5 10 5 10
49 ognl net.sf.saxon.s9api 6 5 6 5
50 org.apache.commons.codec ognl 6 6 6 6
51 org.apache.commons.collections org.apache.commons.codec 800 6 17 6 783
52 org.apache.commons.collections4 org.apache.commons.collections 800 17 783
53 org.apache.commons.io org.apache.commons.collections4 22 800 22 17 783
54 org.apache.commons.jexl2 org.apache.commons.io 15 22 15 22
55 org.apache.commons.jexl3 org.apache.commons.jexl2 15 15
56 org.apache.commons.lang3 org.apache.commons.jexl3 15 423 15 292 131
57 org.apache.commons.ognl org.apache.commons.lang3 6 423 6 292 131
58 org.apache.commons.text org.apache.commons.ognl 6 272 6 220 52
59 org.apache.directory.ldap.client.api org.apache.commons.text 1 272 1 220 52
60 org.apache.hc.core5.function org.apache.directory.ldap.client.api 1 1 1 1
61 org.apache.hc.core5.http org.apache.hc.core5.function 1 2 39 1 1 2 39 1
62 org.apache.hc.core5.net org.apache.hc.core5.http 1 2 2 39 1 2 2 39
63 org.apache.hc.core5.util org.apache.hc.core5.net 24 2 18 2 6
64 org.apache.http org.apache.hc.core5.util 27 3 70 24 25 2 3 62 18 8 6
65 org.apache.ibatis.jdbc org.apache.http 6 27 3 70 25 6 2 3 62 8
66 org.apache.shiro.codec org.apache.ibatis.jdbc 6 1 6 1
67 org.apache.shiro.jndi org.apache.shiro.codec 1 1 1 1
68 org.codehaus.groovy.control org.apache.shiro.jndi 1 1 1
69 org.dom4j org.codehaus.groovy.control 20 1 1 20
70 org.hibernate org.dom4j 7 20 7 20
71 org.jooq org.hibernate 1 7 1 7
72 org.json org.jooq 1 236 1 198 38
73 org.mvel2 org.json 16 236 16 198 38
74 org.springframework.beans org.mvel2 16 26 16 26
75 org.springframework.cache org.springframework.beans 13 26 13 26
76 org.springframework.http org.springframework.cache 14 70 13 14 60 10 13
77 org.springframework.jdbc.core org.springframework.http 10 14 70 14 10 60 10
78 org.springframework.jdbc.object org.springframework.jdbc.core 9 10 9 10
79 org.springframework.jndi org.springframework.jdbc.object 1 9 1 9
80 org.springframework.ldap org.springframework.jndi 42 1 28 1 14
81 org.springframework.security.web.savedrequest org.springframework.ldap 42 6 28 14 6
82 org.springframework.ui org.springframework.security.web.savedrequest 6 32 6 32
83 org.springframework.util org.springframework.ui 139 32 87 52 32
84 org.springframework.validation org.springframework.util 13 139 13 87 52
85 org.springframework.web.client org.springframework.validation 13 3 13 13 3 13
86 org.springframework.web.context.request org.springframework.web.client 13 8 3 13 8 3
87 org.springframework.web.multipart org.springframework.web.context.request 12 8 13 12 8 13
88 org.springframework.web.reactive.function.client org.springframework.web.multipart 2 12 13 2 12 13
89 org.springframework.web.util org.springframework.web.reactive.function.client 2 163 2 138 25
90 org.xml.sax org.springframework.web.util 1 163 1 138 25
91 org.xmlpull.v1 org.xml.sax 3 1 3 1
92 play.mvc org.xmlpull.v1 4 3 4 3
93 play.mvc 4 4
94 ratpack.core.form 3 3
95 ratpack.core.handling 6 4 6 4
96 ratpack.core.http 10 10 10 10
97 ratpack.exec 48 48
98 ratpack.form 3 3
99 ratpack.func 35 35
100 ratpack.handling 6 4 6 4
101 ratpack.http 10 10 10 10
102 ratpack.util 35 35

View File

@@ -7,7 +7,7 @@ Java framework & library support
:widths: auto
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE022` :sub:`Path injection`,`CWE036` :sub:`Path traversal`,`CWE079` :sub:`Cross-site scripting`,`CWE089` :sub:`SQL injection`,`CWE090` :sub:`LDAP injection`,`CWE094` :sub:`Code injection`,`CWE319` :sub:`Cleartext transmission`
Android,``android.*``,45,285,70,,,3,67,,,
Android,``android.*``,45,308,93,,,3,67,,,
`Apache Commons Collections <https://commons.apache.org/proper/commons-collections/>`_,"``org.apache.commons.collections``, ``org.apache.commons.collections4``",,1600,,,,,,,,
`Apache Commons IO <https://commons.apache.org/proper/commons-io/>`_,``org.apache.commons.io``,,22,,,,,,,,
`Apache Commons Lang <https://commons.apache.org/proper/commons-lang/>`_,``org.apache.commons.lang3``,,423,,,,,,,,
@@ -15,9 +15,9 @@ Java framework & library support
`Apache HttpComponents <https://hc.apache.org/>`_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,728,6,,6,,,,,
`JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,,
Java Standard Library,``java.*``,3,506,30,13,,,7,,,10
Java Standard Library,``java.*``,3,524,30,13,,,7,,,10
Java extensions,"``javax.*``, ``jakarta.*``",54,552,32,,,4,,1,1,2
`Spring <https://spring.io/>`_,``org.springframework.*``,29,469,91,,,,19,14,,29
Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.unboundid.ldap.sdk``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jooq``, ``org.mvel2``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,28,151,,,,14,18,,
Totals,,143,5257,408,13,6,10,107,33,1,66
Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.unboundid.ldap.sdk``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jooq``, ``org.mvel2``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``",39,181,151,,,,14,18,,
Totals,,175,5451,431,13,6,10,107,33,1,66

View File

@@ -393,7 +393,7 @@ typeVars(
string nodeName: string ref,
int pos: int ref,
int kind: int ref, // deprecated
int parentid: @typeorcallable ref
int parentid: @classorinterfaceorcallable ref
);
wildcards(
@@ -414,7 +414,7 @@ typeBounds(
typeArgs(
int argumentid: @reftype ref,
int pos: int ref,
int parentid: @typeorcallable ref
int parentid: @classorinterfaceorcallable ref
);
isParameterized(
@@ -487,7 +487,7 @@ hasModifier(
imports(
unique int id: @import,
int holder: @typeorpackage ref,
int holder: @classorinterfaceorpackage ref,
string name: string ref,
int kind: int ref
);
@@ -857,10 +857,9 @@ javadocText(
@javadocParent = @javadoc | @javadocTag;
@javadocElement = @javadocTag | @javadocText;
@typeorpackage = @type | @package;
@typeorcallable = @type | @callable;
@classorinterface = @interface | @class;
@classorinterfaceorpackage = @classorinterface | @package;
@classorinterfaceorcallable = @classorinterface | @callable;
@boundedtype = @typevariable | @wildcard;
@reftype = @classorinterface | @array | @boundedtype;
@classorarray = @class | @array;

View File

@@ -3,24 +3,25 @@ import java
class ExternalData extends @externalDataElement {
string getDataPath() { externalData(this, result, _, _) }
string getQueryPath() { result = getDataPath().regexpReplaceAll("\\.[^.]*$", ".ql") }
string getQueryPath() { result = this.getDataPath().regexpReplaceAll("\\.[^.]*$", ".ql") }
int getNumFields() { result = 1 + max(int i | externalData(this, _, i, _) | i) }
string getField(int index) { externalData(this, _, index, result) }
int getFieldAsInt(int index) { result = getField(index).toInt() }
int getFieldAsInt(int index) { result = this.getField(index).toInt() }
float getFieldAsFloat(int index) { result = getField(index).toFloat() }
float getFieldAsFloat(int index) { result = this.getField(index).toFloat() }
date getFieldAsDate(int index) { result = getField(index).toDate() }
date getFieldAsDate(int index) { result = this.getField(index).toDate() }
string toString() { result = getQueryPath() + ": " + buildTupleString(0) }
string toString() { result = this.getQueryPath() + ": " + this.buildTupleString(0) }
private string buildTupleString(int start) {
start = getNumFields() - 1 and result = getField(start)
start = this.getNumFields() - 1 and result = this.getField(start)
or
start < getNumFields() - 1 and result = getField(start) + "," + buildTupleString(start + 1)
start < this.getNumFields() - 1 and
result = this.getField(start) + "," + this.buildTupleString(start + 1)
}
}
@@ -33,7 +34,7 @@ class DefectExternalData extends ExternalData {
this.getNumFields() = 2
}
string getURL() { result = getField(0) }
string getURL() { result = this.getField(0) }
string getMessage() { result = getField(1) }
string getMessage() { result = this.getField(1) }
}

View File

@@ -47,7 +47,7 @@ class Container extends @container, Top {
*/
string getRelativePath() {
exists(string absPath, string pref |
absPath = getAbsolutePath() and sourceLocationPrefix(pref)
absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
|
absPath = pref and result = ""
or
@@ -74,7 +74,7 @@ class Container extends @container, Top {
* </table>
*/
string getBaseName() {
result = getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
}
/**
@@ -100,7 +100,9 @@ class Container extends @container, Top {
* <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
* </table>
*/
string getExtension() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3) }
string getExtension() {
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3)
}
/**
* Gets the stem of this container, that is, the prefix of its base name up to
@@ -119,7 +121,9 @@ class Container extends @container, Top {
* <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
* </table>
*/
string getStem() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1) }
string getStem() {
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1)
}
/** Gets the parent container of this file or folder, if any. */
Container getParentContainer() { containerparent(result, this) }
@@ -128,20 +132,20 @@ class Container extends @container, Top {
Container getAChildContainer() { this = result.getParentContainer() }
/** Gets a file in this container. */
File getAFile() { result = getAChildContainer() }
File getAFile() { result = this.getAChildContainer() }
/** Gets the file in this container that has the given `baseName`, if any. */
File getFile(string baseName) {
result = getAFile() and
result = this.getAFile() and
result.getBaseName() = baseName
}
/** Gets a sub-folder in this container. */
Folder getAFolder() { result = getAChildContainer() }
Folder getAFolder() { result = this.getAChildContainer() }
/** Gets the sub-folder in this container that has the given `baseName`, if any. */
Folder getFolder(string baseName) {
result = getAFolder() and
result = this.getAFolder() and
result.getBaseName() = baseName
}
@@ -152,7 +156,7 @@ class Container extends @container, Top {
* to provide a different result. To get the absolute path of any `Container`, call
* `Container.getAbsolutePath()` directly.
*/
override string toString() { result = getAbsolutePath() }
override string toString() { result = this.getAbsolutePath() }
}
/** A folder. */
@@ -160,7 +164,7 @@ class Folder extends Container, @folder {
override string getAbsolutePath() { folders(this, result) }
/** Gets the URL of this folder. */
override string getURL() { result = "folder://" + getAbsolutePath() }
override string getURL() { result = "folder://" + this.getAbsolutePath() }
override string getAPrimaryQlClass() { result = "Folder" }
}
@@ -183,7 +187,7 @@ class File extends Container, @file {
* A Java archive file with a ".jar" extension.
*/
class JarFile extends File {
JarFile() { getExtension() = "jar" }
JarFile() { this.getExtension() = "jar" }
/**
* Gets the main attribute with the specified `key`
@@ -195,13 +199,17 @@ class JarFile extends File {
* Gets the "Specification-Version" main attribute
* from this JAR file's manifest.
*/
string getSpecificationVersion() { result = getManifestMainAttribute("Specification-Version") }
string getSpecificationVersion() {
result = this.getManifestMainAttribute("Specification-Version")
}
/**
* Gets the "Implementation-Version" main attribute
* from this JAR file's manifest.
*/
string getImplementationVersion() { result = getManifestMainAttribute("Implementation-Version") }
string getImplementationVersion() {
result = this.getManifestMainAttribute("Implementation-Version")
}
/**
* Gets the per-entry attribute for the specified `entry` and `key`

View File

@@ -63,10 +63,10 @@ class Top extends @top {
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
hasLocationInfoAux(filepath, startline, startcolumn, endline, endcolumn)
this.hasLocationInfoAux(filepath, startline, startcolumn, endline, endcolumn)
or
exists(string outFilepath, int outStartline, int outEndline |
hasLocationInfoAux(outFilepath, outStartline, _, outEndline, _) and
this.hasLocationInfoAux(outFilepath, outStartline, _, outEndline, _) and
hasSmapLocationInfo(filepath, startline, startcolumn, endline, endcolumn, outFilepath,
outStartline, outEndline)
)
@@ -103,7 +103,7 @@ class Top extends @top {
/**
* Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
*/
final string getPrimaryQlClasses() { result = concat(getAPrimaryQlClass(), ",") }
final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") }
/**
* Gets the name of a primary CodeQL class to which this element belongs.

View File

@@ -51,7 +51,7 @@ class Annotation extends @annotation, Expr {
Expr getValue(string name) { filteredAnnotValue(this, this.getAnnotationElement(name), result) }
/** Gets the element being annotated. */
Element getTarget() { result = getAnnotatedElement() }
Element getTarget() { result = this.getAnnotatedElement() }
override string toString() { result = this.getType().getName() }
@@ -67,8 +67,8 @@ class Annotation extends @annotation, Expr {
* expression defined for the value.
*/
Expr getAValue(string name) {
getType().getAnnotationElement(name).getType() instanceof Array and
exists(Expr value | value = getValue(name) |
this.getType().getAnnotationElement(name).getType() instanceof Array and
exists(Expr value | value = this.getValue(name) |
if value instanceof ArrayInit then result = value.(ArrayInit).getAnInit() else result = value
)
}
@@ -104,7 +104,7 @@ class Annotatable extends Element {
/** Holds if this element has the specified annotation. */
predicate hasAnnotation(string package, string name) {
exists(AnnotationType at | at = getAnAnnotation().getType() |
exists(AnnotationType at | at = this.getAnAnnotation().getType() |
at.nestedName() = name and at.getPackage().getName() = package
)
}
@@ -118,7 +118,7 @@ class Annotatable extends Element {
* annotation attached to it for the specified `category`.
*/
predicate suppressesWarningsAbout(string category) {
category = getAnAnnotation().(SuppressWarningsAnnotation).getASuppressedWarning()
category = this.getAnAnnotation().(SuppressWarningsAnnotation).getASuppressedWarning()
or
this.(Member).getDeclaringType().suppressesWarningsAbout(category)
or

View File

@@ -150,7 +150,7 @@ private module ControlFlowGraphImpl {
* `TypeThrowable` which results in both `TypeError` and `TypeRuntimeException`.
*/
UncheckedThrowableType getAnUncheckedSubtype() {
result = this.(UncheckedThrowableType)
result = this
or
result instanceof TypeError and this instanceof TypeThrowable
or
@@ -528,13 +528,13 @@ private module ControlFlowGraphImpl {
/** Gets the first child node, if any. */
ControlFlowNode firstChild() {
result = getChildNode(-1)
result = this.getChildNode(-1)
or
result = getChildNode(0) and not exists(getChildNode(-1))
result = this.getChildNode(0) and not exists(this.getChildNode(-1))
}
/** Holds if this CFG node has any child nodes. */
predicate isLeafNode() { not exists(getChildNode(_)) }
predicate isLeafNode() { not exists(this.getChildNode(_)) }
/** Holds if this node can finish with a `normalCompletion`. */
predicate mayCompleteNormally() {
@@ -1222,10 +1222,10 @@ class ConditionNode extends ControlFlowNode {
ControlFlowNode getABranchSuccessor(boolean branch) { result = branchSuccessor(this, branch) }
/** Gets a true-successor of the `ConditionNode`. */
ControlFlowNode getATrueSuccessor() { result = getABranchSuccessor(true) }
ControlFlowNode getATrueSuccessor() { result = this.getABranchSuccessor(true) }
/** Gets a false-successor of the `ConditionNode`. */
ControlFlowNode getAFalseSuccessor() { result = getABranchSuccessor(false) }
ControlFlowNode getAFalseSuccessor() { result = this.getABranchSuccessor(false) }
/** Gets the condition of this `ConditionNode`. This is equal to the node itself. */
Expr getCondition() { result = this }

View File

@@ -27,7 +27,7 @@ abstract class ConversionSite extends Expr {
/**
* Whether this conversion site actually induces a conversion.
*/
predicate isTrivial() { getConversionTarget() = getConversionSource() }
predicate isTrivial() { this.getConversionTarget() = this.getConversionSource() }
/**
* Whether this conversion is implicit.

View File

@@ -34,10 +34,10 @@ class Element extends @element, Top {
* Elements pertaining to source files may include generated elements
* not visible in source code, such as implicit default constructors.
*/
predicate fromSource() { getCompilationUnit().getExtension() = "java" }
predicate fromSource() { this.getCompilationUnit().getExtension() = "java" }
/** Gets the compilation unit that this element belongs to. */
CompilationUnit getCompilationUnit() { result = getFile() }
CompilationUnit getCompilationUnit() { result = this.getFile() }
/** Cast this element to a `Documentable`. */
Documentable getDoc() { result = this }

View File

@@ -86,13 +86,15 @@ class Expr extends ExprParent, @expr {
* explicit constructor invocation statement.
*/
getEnclosingCallable().isStatic()
this.getEnclosingCallable().isStatic()
or
getParent+() instanceof ThisConstructorInvocationStmt
this.getParent+() instanceof ThisConstructorInvocationStmt
or
getParent+() instanceof SuperConstructorInvocationStmt
this.getParent+() instanceof SuperConstructorInvocationStmt
or
exists(LambdaExpr lam | lam.asMethod() = getEnclosingCallable() and lam.isInStaticContext())
exists(LambdaExpr lam |
lam.asMethod() = this.getEnclosingCallable() and lam.isInStaticContext()
)
}
/** Holds if this expression is parenthesized. */
@@ -116,7 +118,7 @@ private predicate primitiveOrString(Type t) {
*/
class CompileTimeConstantExpr extends Expr {
CompileTimeConstantExpr() {
primitiveOrString(getType()) and
primitiveOrString(this.getType()) and
(
// Literals of primitive type and literals of type `String`.
this instanceof Literal
@@ -164,7 +166,7 @@ class CompileTimeConstantExpr extends Expr {
*/
pragma[nomagic]
string getStringValue() {
result = this.(StringLiteral).getRepresentedString()
result = this.(StringLiteral).getValue()
or
result =
this.(AddExpr).getLeftOperand().(CompileTimeConstantExpr).getStringValue() +
@@ -296,18 +298,15 @@ class CompileTimeConstantExpr extends Expr {
*
* Note that this does not handle the following cases:
*
* - values of type `long`,
* - `char` literals.
* - values of type `long`.
*/
cached
int getIntValue() {
exists(IntegralType t | this.getType() = t | t.getName().toLowerCase() != "long") and
(
exists(string lit | lit = this.(Literal).getValue() |
// `char` literals may get parsed incorrectly, so disallow.
not this instanceof CharacterLiteral and
result = lit.toInt()
)
result = this.(IntegerLiteral).getIntValue()
or
result = this.(CharacterLiteral).getCodePointValue()
or
exists(CastExpr cast, int val |
cast = this and val = cast.getExpr().(CompileTimeConstantExpr).getIntValue()
@@ -425,9 +424,9 @@ class ArrayCreationExpr extends Expr, @arraycreationexpr {
* Gets the size of the first dimension, if it can be statically determined.
*/
int getFirstDimensionSize() {
if exists(getInit())
then result = getInit().getSize()
else result = getDimension(0).(CompileTimeConstantExpr).getIntValue()
if exists(this.getInit())
then result = this.getInit().getSize()
else result = this.getDimension(0).(CompileTimeConstantExpr).getIntValue()
}
/** Gets a printable representation of this expression. */
@@ -463,7 +462,7 @@ class ArrayInit extends Expr, @arrayinit {
* Gets the number of expressions in this initializer, that is, the size the
* created array will have.
*/
int getSize() { result = count(getAnInit()) }
int getSize() { result = count(this.getAnInit()) }
/** Gets a printable representation of this expression. */
override string toString() { result = "{...}" }
@@ -632,9 +631,9 @@ class Literal extends Expr, @literal {
class BooleanLiteral extends Literal, @booleanliteral {
/** Gets the boolean representation of this literal. */
boolean getBooleanValue() {
result = true and getValue() = "true"
result = true and this.getValue() = "true"
or
result = false and getValue() = "false"
result = false and this.getValue() = "false"
}
override string getAPrimaryQlClass() { result = "BooleanLiteral" }
@@ -657,7 +656,7 @@ class BooleanLiteral extends Literal, @booleanliteral {
*/
class IntegerLiteral extends Literal, @integerliteral {
/** Gets the int representation of this literal. */
int getIntValue() { result = getValue().toInt() }
int getIntValue() { result = this.getValue().toInt() }
override string getAPrimaryQlClass() { result = "IntegerLiteral" }
}
@@ -693,7 +692,7 @@ class FloatingPointLiteral extends Literal, @floatingpointliteral {
* Gets the value of this literal as CodeQL 64-bit `float`. The value will
* be parsed as Java 32-bit `float` and then converted to a CodeQL `float`.
*/
float getFloatValue() { result = getValue().toFloat() }
float getFloatValue() { result = this.getValue().toFloat() }
override string getAPrimaryQlClass() { result = "FloatingPointLiteral" }
}
@@ -709,14 +708,45 @@ class DoubleLiteral extends Literal, @doubleliteral {
* Gets the value of this literal as CodeQL 64-bit `float`. The result will
* have the same effective value as the Java `double` literal.
*/
float getDoubleValue() { result = getValue().toFloat() }
float getDoubleValue() { result = this.getValue().toFloat() }
override string getAPrimaryQlClass() { result = "DoubleLiteral" }
}
bindingset[s]
private int fromHex(string s) {
exists(string digits | s.toUpperCase() = digits |
result =
sum(int i |
|
"0123456789ABCDEF".indexOf(digits.charAt(i)).bitShiftLeft((digits.length() - i - 1) * 4)
)
)
}
/** A character literal. For example, `'\n'`. */
class CharacterLiteral extends Literal, @characterliteral {
override string getAPrimaryQlClass() { result = "CharacterLiteral" }
/**
* Gets a string which consists of the single character represented by
* this literal.
*
* Unicode surrogate characters (U+D800 to U+DFFF) have the replacement character
* U+FFFD as result instead.
*/
override string getValue() { result = super.getValue() }
/**
* Gets the Unicode code point value of the character represented by
* this literal. The result is the same as if the Java code had cast
* the character to an `int`.
*/
int getCodePointValue() {
if this.getLiteral().matches("'\\u____'")
then result = fromHex(this.getLiteral().substring(3, 7))
else result.toUnicode() = this.getValue()
}
}
/**
@@ -730,12 +760,24 @@ class CharacterLiteral extends Literal, @characterliteral {
*/
class StringLiteral extends Literal, @stringliteral {
/**
* Gets the string represented by this string literal, that is, the content
* of the literal without enclosing quotes and with escape sequences translated.
*
* Unpaired Unicode surrogate characters (U+D800 to U+DFFF) are replaced with the
* replacement character U+FFFD.
*/
override string getValue() { result = super.getValue() }
/**
* DEPRECATED: This predicate will be removed in a future version because
* it is just an alias for `getValue()`; that predicate should be used instead.
*
* Gets the literal string without the quotes.
*/
string getRepresentedString() { result = getValue() }
deprecated string getRepresentedString() { result = this.getValue() }
/** Holds if this string literal is a text block (`""" ... """`). */
predicate isTextBlock() { getLiteral().matches("\"\"\"%") }
predicate isTextBlock() { this.getLiteral().matches("\"\"\"%") }
override string getAPrimaryQlClass() { result = "StringLiteral" }
}
@@ -1184,7 +1226,7 @@ class LambdaExpr extends FunctionalExpr, @lambdaexpr {
* Gets the implicit method corresponding to this lambda expression.
* The parameters of the lambda expression are the parameters of this method.
*/
override Method asMethod() { result = getAnonymousClass().getAMethod() }
override Method asMethod() { result = this.getAnonymousClass().getAMethod() }
/** Holds if the body of this lambda is an expression. */
predicate hasExprBody() { lambdaKind(this, 0) }
@@ -1194,11 +1236,11 @@ class LambdaExpr extends FunctionalExpr, @lambdaexpr {
/** Gets the body of this lambda expression, if it is an expression. */
Expr getExprBody() {
hasExprBody() and result = asMethod().getBody().getAChild().(ReturnStmt).getResult()
this.hasExprBody() and result = this.asMethod().getBody().getAChild().(ReturnStmt).getResult()
}
/** Gets the body of this lambda expression, if it is a statement. */
BlockStmt getStmtBody() { hasStmtBody() and result = asMethod().getBody() }
BlockStmt getStmtBody() { this.hasStmtBody() and result = this.asMethod().getBody() }
/** Gets a printable representation of this expression. */
override string toString() { result = "...->..." }
@@ -1223,7 +1265,29 @@ class MemberRefExpr extends FunctionalExpr, @memberref {
* (if the reference is to a constructor) or an array creation expression (if the reference
* is to an array constructor).
*/
override Method asMethod() { result = getAnonymousClass().getAMethod() }
override Method asMethod() { result = this.getAnonymousClass().getAMethod() }
/**
* Gets the receiver type whose member this expression refers to. The result might not be
* the type which actually declares the member. For example, for the member reference `ArrayList::toString`,
* this predicate has the result `java.util.ArrayList`, the type explicitly referred to, while
* `getReferencedCallable` will have `java.util.AbstractCollection.toString` as result, which `ArrayList` inherits.
*/
RefType getReceiverType() {
exists(Stmt stmt, Expr resultExpr |
stmt = asMethod().getBody().(SingletonBlock).getStmt() and
(
resultExpr = stmt.(ReturnStmt).getResult()
or
// Note: Currently never an ExprStmt, but might change once https://github.com/github/codeql/issues/3605 is fixed
resultExpr = stmt.(ExprStmt).getExpr()
)
|
result = resultExpr.(MethodAccess).getReceiverType() or
result = resultExpr.(ClassInstanceExpr).getConstructedType() or
result = resultExpr.(ArrayCreationExpr).getType()
)
}
/**
* Gets the method or constructor referenced by this member reference expression.
@@ -1274,16 +1338,16 @@ class ConditionalExpr extends Expr, @conditionalexpr {
* it is `getFalseExpr()`.
*/
Expr getBranchExpr(boolean branch) {
branch = true and result = getTrueExpr()
branch = true and result = this.getTrueExpr()
or
branch = false and result = getFalseExpr()
branch = false and result = this.getFalseExpr()
}
/**
* Gets the expressions that is evaluated by one of the branches (`true`
* or `false` branch) of this conditional expression.
*/
Expr getABranchExpr() { result = getBranchExpr(_) }
Expr getABranchExpr() { result = this.getBranchExpr(_) }
/** Gets a printable representation of this expression. */
override string toString() { result = "...?...:..." }
@@ -1308,7 +1372,7 @@ class SwitchExpr extends Expr, StmtParent, @switchexpr {
* Gets a case of this `switch` expression,
* which may be either a normal `case` or a `default`.
*/
SwitchCase getACase() { result = getAConstCase() or result = getDefaultCase() }
SwitchCase getACase() { result = this.getAConstCase() or result = this.getDefaultCase() }
/** Gets a (non-default) `case` of this `switch` expression. */
ConstCase getAConstCase() { result.getParent() = this }
@@ -1321,7 +1385,7 @@ class SwitchExpr extends Expr, StmtParent, @switchexpr {
/** Gets a result expression of this `switch` expression. */
Expr getAResult() {
result = getACase().getRuleExpression()
result = this.getACase().getRuleExpression()
or
exists(YieldStmt yield | yield.(JumpStmt).getTarget() = this and result = yield.getValue())
}
@@ -1336,21 +1400,17 @@ class SwitchExpr extends Expr, StmtParent, @switchexpr {
class InstanceOfExpr extends Expr, @instanceofexpr {
/** Gets the expression on the left-hand side of the `instanceof` operator. */
Expr getExpr() {
if isPattern()
then result = getLocalVariableDeclExpr().getInit()
if this.isPattern()
then result = this.getLocalVariableDeclExpr().getInit()
else result.isNthChildOf(this, 0)
}
/**
* PREVIEW FEATURE in Java 14. Subject to removal in a future release.
*
* Holds if this `instanceof` expression uses pattern matching.
*/
predicate isPattern() { exists(getLocalVariableDeclExpr()) }
predicate isPattern() { exists(this.getLocalVariableDeclExpr()) }
/**
* PREVIEW FEATURE in Java 14. Subject to removal in a future release.
*
* Gets the local variable declaration of this `instanceof` expression if pattern matching is used.
*/
LocalVariableDeclExpr getLocalVariableDeclExpr() { result.isNthChildOf(this, 0) }
@@ -1359,7 +1419,7 @@ class InstanceOfExpr extends Expr, @instanceofexpr {
Expr getTypeName() { result.isNthChildOf(this, 1) }
/** Gets the type this `instanceof` expression checks for. */
RefType getCheckedType() { result = getTypeName().getType() }
RefType getCheckedType() { result = this.getTypeName().getType() }
/** Gets a printable representation of this expression. */
override string toString() { result = "...instanceof..." }
@@ -1457,7 +1517,7 @@ class TypeLiteral extends Expr, @typeliteral {
* Gets the type this type literal refers to. For example for `String.class` the
* result is the type representing `String`.
*/
Type getReferencedType() { result = getTypeName().getType() }
Type getReferencedType() { result = this.getTypeName().getType() }
/** Gets a printable representation of this expression. */
override string toString() { result = this.getTypeName().toString() + ".class" }
@@ -1482,15 +1542,15 @@ abstract class InstanceAccess extends Expr {
* This never holds for accesses in lambda expressions as they cannot access
* their own instance directly.
*/
predicate isOwnInstanceAccess() { not isEnclosingInstanceAccess(_) }
predicate isOwnInstanceAccess() { not this.isEnclosingInstanceAccess(_) }
/** Holds if this instance access is to an enclosing instance of type `t`. */
predicate isEnclosingInstanceAccess(RefType t) {
t = getQualifier().getType().(RefType).getSourceDeclaration() and
t != getEnclosingCallable().getDeclaringType()
t = this.getQualifier().getType().(RefType).getSourceDeclaration() and
t != this.getEnclosingCallable().getDeclaringType()
or
not exists(getQualifier()) and
exists(LambdaExpr lam | lam.asMethod() = getEnclosingCallable() |
not exists(this.getQualifier()) and
exists(LambdaExpr lam | lam.asMethod() = this.getEnclosingCallable() |
t = lam.getAnonymousClass().getEnclosingType()
)
}
@@ -1538,7 +1598,7 @@ class VarAccess extends Expr, @varaccess {
Expr getQualifier() { result.getParent() = this }
/** Holds if this variable access has a qualifier. */
predicate hasQualifier() { exists(getQualifier()) }
predicate hasQualifier() { exists(this.getQualifier()) }
/** Gets the variable accessed by this variable access. */
Variable getVariable() { variableBinding(this, result) }
@@ -1580,11 +1640,11 @@ class VarAccess extends Expr, @varaccess {
*/
predicate isLocal() {
// The access has no qualifier, or...
not hasQualifier()
not this.hasQualifier()
or
// the qualifier is either `this` or `A.this`, where `A` is the enclosing type, or
// the qualifier is either `super` or `A.super`, where `A` is the enclosing type.
getQualifier().(InstanceAccess).isOwnInstanceAccess()
this.getQualifier().(InstanceAccess).isOwnInstanceAccess()
}
override string getAPrimaryQlClass() { result = "VarAccess" }
@@ -1626,7 +1686,7 @@ class MethodAccess extends Expr, Call, @methodaccess {
override Expr getQualifier() { result.isNthChildOf(this, -1) }
/** Holds if this method access has a qualifier. */
predicate hasQualifier() { exists(getQualifier()) }
predicate hasQualifier() { exists(this.getQualifier()) }
/** Gets an argument supplied to the method that is invoked using this method access. */
override Expr getAnArgument() { result.getIndex() >= 0 and result.getParent() = this }
@@ -1663,9 +1723,9 @@ class MethodAccess extends Expr, Call, @methodaccess {
* the enclosing type if there is no qualifier.
*/
RefType getReceiverType() {
result = getQualifier().getType()
result = this.getQualifier().getType()
or
not hasQualifier() and result = getEnclosingCallable().getDeclaringType()
not this.hasQualifier() and result = this.getEnclosingCallable().getDeclaringType()
}
/**
@@ -1841,7 +1901,7 @@ class Call extends ExprParent, @caller {
Callable getCallee() { callableBinding(this, result) }
/** Gets the callable invoking this call. */
Callable getCaller() { result = getEnclosingCallable() }
Callable getCaller() { result = this.getEnclosingCallable() }
}
/** A polymorphic call to an instance method. */
@@ -2042,14 +2102,14 @@ class Argument extends Expr {
}
/** Holds if this argument is part of an implicit varargs array. */
predicate isVararg() { isNthVararg(_) }
predicate isVararg() { this.isNthVararg(_) }
/**
* Holds if this argument is part of an implicit varargs array at the
* given array index.
*/
predicate isNthVararg(int arrayindex) {
not isExplicitVarargsArray() and
not this.isExplicitVarargsArray() and
exists(Callable tgt |
call.getCallee() = tgt and
tgt.isVarargs() and

View File

@@ -38,7 +38,7 @@ import Type
*
* For example, `X` in `class X<T> { }`.
*/
class GenericType extends RefType {
class GenericType extends ClassOrInterface {
GenericType() { typeVars(_, _, _, _, this) }
/**
@@ -69,12 +69,12 @@ class GenericType extends RefType {
/**
* Gets a type parameter of this generic type.
*/
TypeVariable getATypeParameter() { result = getTypeParameter(_) }
TypeVariable getATypeParameter() { result = this.getTypeParameter(_) }
/**
* Gets the number of type parameters of this generic type.
*/
int getNumberOfTypeParameters() { result = strictcount(getATypeParameter()) }
int getNumberOfTypeParameters() { result = strictcount(this.getATypeParameter()) }
override string getAPrimaryQlClass() { result = "GenericType" }
}
@@ -107,7 +107,7 @@ abstract class BoundedType extends RefType, @boundedtype {
TypeBound getATypeBound() { result.getBoundedType() = this }
/** Gets the first type bound for this type, if any. */
TypeBound getFirstTypeBound() { result = getATypeBound() and result.getPosition() = 0 }
TypeBound getFirstTypeBound() { result = this.getATypeBound() and result.getPosition() = 0 }
/**
* Gets an upper type bound of this type, or `Object`
@@ -123,9 +123,9 @@ abstract class BoundedType extends RefType, @boundedtype {
/** Gets a transitive upper bound for this type that is not itself a bounded type. */
RefType getAnUltimateUpperBoundType() {
result = getUpperBoundType() and not result instanceof BoundedType
result = this.getUpperBoundType() and not result instanceof BoundedType
or
result = getUpperBoundType().(BoundedType).getAnUltimateUpperBoundType()
result = this.getUpperBoundType().(BoundedType).getAnUltimateUpperBoundType()
}
override string getAPrimaryQlClass() { result = "BoundedType" }
@@ -139,7 +139,7 @@ abstract class BoundedType extends RefType, @boundedtype {
*/
class TypeVariable extends BoundedType, @typevariable {
/** Gets the generic type that is parameterized by this type parameter, if any. */
RefType getGenericType() { typeVars(this, _, _, _, result) }
GenericType getGenericType() { typeVars(this, _, _, _, result) }
/** Gets the generic callable that is parameterized by this type parameter, if any. */
GenericCallable getGenericCallable() { typeVars(this, _, _, _, result) }
@@ -168,8 +168,8 @@ class TypeVariable extends BoundedType, @typevariable {
/** Gets the lexically enclosing package of this type parameter, if any. */
override Package getPackage() {
result = getGenericType().getPackage() or
result = getGenericCallable().getDeclaringType().getPackage()
result = this.getGenericType().getPackage() or
result = this.getGenericCallable().getDeclaringType().getPackage()
}
/** Finds a type that was supplied for this parameter. */
@@ -190,9 +190,9 @@ class TypeVariable extends BoundedType, @typevariable {
/** Finds a non-typevariable type that was transitively supplied for this parameter. */
RefType getAnUltimatelySuppliedType() {
result = getASuppliedType() and not result instanceof TypeVariable
result = this.getASuppliedType() and not result instanceof TypeVariable
or
result = getASuppliedType().(TypeVariable).getAnUltimatelySuppliedType()
result = this.getASuppliedType().(TypeVariable).getAnUltimatelySuppliedType()
}
override string getAPrimaryQlClass() { result = "TypeVariable" }
@@ -261,7 +261,7 @@ class Wildcard extends BoundedType, @wildcard {
* Holds if this is the unconstrained wildcard `?`.
*/
predicate isUnconstrained() {
not hasLowerBound() and
not this.hasLowerBound() and
wildcards(this, "?", _)
}
@@ -321,7 +321,7 @@ class TypeBound extends @typebound {
* For example, `List<Number>` is a parameterization of
* the generic type `List<E>`, where `E` is a type parameter.
*/
class ParameterizedType extends RefType {
class ParameterizedType extends ClassOrInterface {
ParameterizedType() {
typeArgs(_, _, this) or
typeVars(_, _, _, _, this)
@@ -367,7 +367,9 @@ class ParameterizedType extends RefType {
}
/** Holds if this type originates from source code. */
override predicate fromSource() { typeVars(_, _, _, _, this) and RefType.super.fromSource() }
override predicate fromSource() {
typeVars(_, _, _, _, this) and ClassOrInterface.super.fromSource()
}
override string getAPrimaryQlClass() { result = "ParameterizedType" }
}
@@ -451,12 +453,12 @@ class GenericCallable extends Callable {
/**
* Gets a type parameter of this generic callable.
*/
TypeVariable getATypeParameter() { result = getTypeParameter(_) }
TypeVariable getATypeParameter() { result = this.getTypeParameter(_) }
/**
* Gets the number of type parameters of this generic callable.
*/
int getNumberOfTypeParameters() { result = strictcount(getATypeParameter()) }
int getNumberOfTypeParameters() { result = strictcount(this.getATypeParameter()) }
}
/**
@@ -484,10 +486,10 @@ class GenericCall extends Call {
/** Gets a type argument of the call for the given `TypeVariable`. */
RefType getATypeArgument(TypeVariable v) {
result = getAnExplicitTypeArgument(v)
result = this.getAnExplicitTypeArgument(v)
or
not exists(getAnExplicitTypeArgument(v)) and
result = getAnInferredTypeArgument(v)
not exists(this.getAnExplicitTypeArgument(v)) and
result = this.getAnInferredTypeArgument(v)
}
}

View File

@@ -25,7 +25,7 @@ class ImportType extends Import {
ImportType() { imports(this, _, _, 1) }
/** Gets the imported type. */
RefType getImportedType() { imports(this, result, _, _) }
ClassOrInterface getImportedType() { imports(this, result, _, _) }
override string toString() { result = "import " + this.getImportedType().toString() }
@@ -44,7 +44,7 @@ class ImportOnDemandFromType extends Import {
ImportOnDemandFromType() { imports(this, _, _, 2) }
/** Gets the type from which accessible nested types are imported. */
RefType getTypeHoldingImport() { imports(this, result, _, _) }
ClassOrInterface getTypeHoldingImport() { imports(this, result, _, _) }
/** Gets an imported type. */
NestedType getAnImport() { result.getEnclosingType() = this.getTypeHoldingImport() }
@@ -87,7 +87,7 @@ class ImportStaticOnDemand extends Import {
ImportStaticOnDemand() { imports(this, _, _, 4) }
/** Gets the type from which accessible static members are imported. */
RefType getTypeHoldingImport() { imports(this, result, _, _) }
ClassOrInterface getTypeHoldingImport() { imports(this, result, _, _) }
/** Gets an imported type. */
NestedType getATypeImport() { result.getEnclosingType() = this.getTypeHoldingImport() }
@@ -118,7 +118,7 @@ class ImportStaticTypeMember extends Import {
ImportStaticTypeMember() { imports(this, _, _, 5) }
/** Gets the type from which static members with a given name are imported. */
RefType getTypeHoldingImport() { imports(this, result, _, _) }
ClassOrInterface getTypeHoldingImport() { imports(this, result, _, _) }
/** Gets the name of the imported member(s). */
override string getName() { imports(this, _, result, _) }

View File

@@ -19,12 +19,12 @@ class TypeCloneable extends Interface {
/** The class `java.lang.ProcessBuilder`. */
class TypeProcessBuilder extends Class {
TypeProcessBuilder() { hasQualifiedName("java.lang", "ProcessBuilder") }
TypeProcessBuilder() { this.hasQualifiedName("java.lang", "ProcessBuilder") }
}
/** The class `java.lang.Runtime`. */
class TypeRuntime extends Class {
TypeRuntime() { hasQualifiedName("java.lang", "Runtime") }
TypeRuntime() { this.hasQualifiedName("java.lang", "Runtime") }
}
/** The class `java.lang.String`. */
@@ -143,22 +143,22 @@ class ImmutableType extends Type {
// --- Java IO ---
/** The interface `java.io.Serializable`. */
class TypeSerializable extends Interface {
TypeSerializable() { hasQualifiedName("java.io", "Serializable") }
TypeSerializable() { this.hasQualifiedName("java.io", "Serializable") }
}
/** The interface `java.io.ObjectOutput`. */
class TypeObjectOutput extends Interface {
TypeObjectOutput() { hasQualifiedName("java.io", "ObjectOutput") }
TypeObjectOutput() { this.hasQualifiedName("java.io", "ObjectOutput") }
}
/** The type `java.io.ObjectOutputStream`. */
class TypeObjectOutputStream extends RefType {
TypeObjectOutputStream() { hasQualifiedName("java.io", "ObjectOutputStream") }
TypeObjectOutputStream() { this.hasQualifiedName("java.io", "ObjectOutputStream") }
}
/** The type `java.io.ObjectInputStream`. */
class TypeObjectInputStream extends RefType {
TypeObjectInputStream() { hasQualifiedName("java.io", "ObjectInputStream") }
TypeObjectInputStream() { this.hasQualifiedName("java.io", "ObjectInputStream") }
}
/** The class `java.nio.file.Paths`. */
@@ -196,8 +196,8 @@ class ProcessBuilderConstructor extends Constructor, ExecCallable {
*/
class MethodProcessBuilderCommand extends Method, ExecCallable {
MethodProcessBuilderCommand() {
hasName("command") and
getDeclaringType() instanceof TypeProcessBuilder
this.hasName("command") and
this.getDeclaringType() instanceof TypeProcessBuilder
}
override int getAnExecutedArgument() { result = 0 }
@@ -208,8 +208,8 @@ class MethodProcessBuilderCommand extends Method, ExecCallable {
*/
class MethodRuntimeExec extends Method, ExecCallable {
MethodRuntimeExec() {
hasName("exec") and
getDeclaringType() instanceof TypeRuntime
this.hasName("exec") and
this.getDeclaringType() instanceof TypeRuntime
}
override int getAnExecutedArgument() { result = 0 }
@@ -220,8 +220,8 @@ class MethodRuntimeExec extends Method, ExecCallable {
*/
class MethodSystemGetenv extends Method {
MethodSystemGetenv() {
hasName("getenv") and
getDeclaringType() instanceof TypeSystem
this.hasName("getenv") and
this.getDeclaringType() instanceof TypeSystem
}
}
@@ -230,8 +230,8 @@ class MethodSystemGetenv extends Method {
*/
class MethodSystemGetProperty extends Method {
MethodSystemGetProperty() {
hasName("getProperty") and
getDeclaringType() instanceof TypeSystem
this.hasName("getProperty") and
this.getDeclaringType() instanceof TypeSystem
}
}
@@ -239,7 +239,7 @@ class MethodSystemGetProperty extends Method {
* An access to a method named `getProperty` on class `java.lang.System`.
*/
class MethodAccessSystemGetProperty extends MethodAccess {
MethodAccessSystemGetProperty() { getMethod() instanceof MethodSystemGetProperty }
MethodAccessSystemGetProperty() { this.getMethod() instanceof MethodSystemGetProperty }
/**
* Holds if this call has a compile-time constant first argument with the value `propertyName`.
@@ -255,8 +255,11 @@ class MethodAccessSystemGetProperty extends MethodAccess {
*/
class MethodExit extends Method {
MethodExit() {
hasName("exit") and
(getDeclaringType() instanceof TypeRuntime or getDeclaringType() instanceof TypeSystem)
this.hasName("exit") and
(
this.getDeclaringType() instanceof TypeRuntime or
this.getDeclaringType() instanceof TypeSystem
)
}
}
@@ -266,10 +269,10 @@ class MethodExit extends Method {
*/
class WriteObjectMethod extends Method {
WriteObjectMethod() {
hasName("writeObject") and
this.hasName("writeObject") and
(
getDeclaringType() instanceof TypeObjectOutputStream or
getDeclaringType() instanceof TypeObjectOutput
this.getDeclaringType() instanceof TypeObjectOutputStream or
this.getDeclaringType() instanceof TypeObjectOutput
)
}
}
@@ -293,16 +296,16 @@ class ReadObjectMethod extends Method {
/** The method `Class.getName()`. */
class ClassNameMethod extends Method {
ClassNameMethod() {
hasName("getName") and
getDeclaringType() instanceof TypeClass
this.hasName("getName") and
this.getDeclaringType() instanceof TypeClass
}
}
/** The method `Class.getSimpleName()`. */
class ClassSimpleNameMethod extends Method {
ClassSimpleNameMethod() {
hasName("getSimpleName") and
getDeclaringType() instanceof TypeClass
this.hasName("getSimpleName") and
this.getDeclaringType() instanceof TypeClass
}
}
@@ -334,24 +337,24 @@ class MethodMathMax extends Method {
/** The field `System.in`. */
class SystemIn extends Field {
SystemIn() {
hasName("in") and
getDeclaringType() instanceof TypeSystem
this.hasName("in") and
this.getDeclaringType() instanceof TypeSystem
}
}
/** The field `System.out`. */
class SystemOut extends Field {
SystemOut() {
hasName("out") and
getDeclaringType() instanceof TypeSystem
this.hasName("out") and
this.getDeclaringType() instanceof TypeSystem
}
}
/** The field `System.err`. */
class SystemErr extends Field {
SystemErr() {
hasName("err") and
getDeclaringType() instanceof TypeSystem
this.hasName("err") and
this.getDeclaringType() instanceof TypeSystem
}
}

View File

@@ -25,7 +25,7 @@ class SuppressWarningsAnnotation extends Annotation {
}
/** Gets the name of a warning suppressed by this annotation. */
string getASuppressedWarning() { result = getASuppressedWarningLiteral().getRepresentedString() }
string getASuppressedWarning() { result = this.getASuppressedWarningLiteral().getValue() }
}
/** A `@Target` annotation. */

View File

@@ -26,27 +26,27 @@ class MXBean extends ManagedBean {
*/
class RegisteredManagedBeanImpl extends Class {
RegisteredManagedBeanImpl() {
getAnAncestor() instanceof ManagedBean and
this.getAnAncestor() instanceof ManagedBean and
exists(JMXRegistrationCall registerCall | registerCall.getObjectArgument().getType() = this)
}
/**
* Gets a managed bean that this registered bean class implements.
*/
ManagedBean getAnImplementedManagedBean() { result = getAnAncestor() }
ManagedBean getAnImplementedManagedBean() { result = this.getAnAncestor() }
}
/**
* A call that registers an object with the `MBeanServer`, directly or indirectly.
*/
class JMXRegistrationCall extends MethodAccess {
JMXRegistrationCall() { getCallee() instanceof JMXRegistrationMethod }
JMXRegistrationCall() { this.getCallee() instanceof JMXRegistrationMethod }
/**
* Gets the argument that represents the object in the registration call.
*/
Expr getObjectArgument() {
result = getArgument(getCallee().(JMXRegistrationMethod).getObjectPosition())
result = this.getArgument(this.getCallee().(JMXRegistrationMethod).getObjectPosition())
}
}
@@ -59,15 +59,15 @@ class JMXRegistrationCall extends MethodAccess {
class JMXRegistrationMethod extends Method {
JMXRegistrationMethod() {
// A direct registration with the `MBeanServer`.
getDeclaringType().hasQualifiedName("javax.management", "MBeanServer") and
getName() = "registerMBean"
this.getDeclaringType().hasQualifiedName("javax.management", "MBeanServer") and
this.getName() = "registerMBean"
or
// The `MBeanServer` is often wrapped by an application specific management class, so identify
// methods that wrap a call to another `JMXRegistrationMethod`.
exists(JMXRegistrationCall c |
// This must be a call to another JMX registration method, where the object argument is an access
// of one of the parameters of this method.
c.getObjectArgument().(VarAccess).getVariable() = getAParameter()
c.getObjectArgument().(VarAccess).getVariable() = this.getAParameter()
)
}
@@ -76,13 +76,13 @@ class JMXRegistrationMethod extends Method {
*/
int getObjectPosition() {
// Passed as the first argument to `registerMBean`.
getDeclaringType().hasQualifiedName("javax.management", "MBeanServer") and
getName() = "registerMBean" and
this.getDeclaringType().hasQualifiedName("javax.management", "MBeanServer") and
this.getName() = "registerMBean" and
result = 0
or
// Identify the position in this method where the object parameter should be passed.
exists(JMXRegistrationCall c |
c.getObjectArgument().(VarAccess).getVariable() = getParameter(result)
c.getObjectArgument().(VarAccess).getVariable() = this.getParameter(result)
)
}
}

View File

@@ -14,7 +14,7 @@ class JavadocParent extends @javadocParent, Top {
JavadocElement getChild(int index) { result = this.getAChild() and result.getIndex() = index }
/** Gets the number of documentation elements attached to this parent. */
int getNumChild() { result = count(getAChild()) }
int getNumChild() { result = count(this.getAChild()) }
/** Gets a documentation element with the specified Javadoc tag name. */
JavadocTag getATag(string name) { result = this.getAChild() and result.getTagName() = name }
@@ -33,7 +33,9 @@ class Javadoc extends JavadocParent, @javadoc {
/** Gets the value of the `@author` tag, if any. */
string getAuthor() { result = this.getATag("@author").getChild(0).toString() }
override string toString() { result = toStringPrefix() + getChild(0) + toStringPostfix() }
override string toString() {
result = this.toStringPrefix() + this.getChild(0) + this.toStringPostfix()
}
private string toStringPrefix() {
if isEolComment(this)
@@ -47,7 +49,7 @@ class Javadoc extends JavadocParent, @javadoc {
if isEolComment(this)
then result = ""
else (
if strictcount(getAChild()) = 1 then result = " */" else result = " ... */"
if strictcount(this.getAChild()) = 1 then result = " */" else result = " ... */"
)
}
@@ -119,10 +121,10 @@ class ThrowsTag extends JavadocTag {
/** A Javadoc `@see` tag. */
class SeeTag extends JavadocTag {
SeeTag() { getTagName() = "@see" }
SeeTag() { this.getTagName() = "@see" }
/** Gets the name of the entity referred to. */
string getReference() { result = getChild(0).toString() }
string getReference() { result = this.getChild(0).toString() }
}
/** A Javadoc `@author` tag. */

View File

@@ -76,11 +76,11 @@ class FreshMap extends ClassInstanceExpr {
* A call to `Map.put(key, value)`.
*/
class MapPutCall extends MethodAccess {
MapPutCall() { getCallee().(MapMethod).hasName("put") }
MapPutCall() { this.getCallee().(MapMethod).hasName("put") }
/** Gets the key argument of this call. */
Expr getKey() { result = getArgument(0) }
Expr getKey() { result = this.getArgument(0) }
/** Gets the value argument of this call. */
Expr getValue() { result = getArgument(1) }
Expr getValue() { result = this.getArgument(1) }
}

View File

@@ -21,7 +21,7 @@ class Member extends Element, Annotatable, Modifiable, @member {
RefType getDeclaringType() { declaresMember(result, this) }
/** Gets the qualified name of this member. */
string getQualifiedName() { result = getDeclaringType().getName() + "." + getName() }
string getQualifiedName() { result = this.getDeclaringType().getName() + "." + this.getName() }
/**
* Holds if this member has the specified name and is declared in the
@@ -33,9 +33,9 @@ class Member extends Element, Annotatable, Modifiable, @member {
/** Holds if this member is package protected, that is, neither public nor private nor protected. */
predicate isPackageProtected() {
not isPrivate() and
not isProtected() and
not isPublic()
not this.isPrivate() and
not this.isProtected() and
not this.isPublic()
}
/**
@@ -78,7 +78,7 @@ class Callable extends StmtParent, Member, @callable {
*/
string getMethodDescriptor() {
exists(string return | return = this.getReturnType().getTypeDescriptor() |
result = "(" + descriptorUpTo(this.getNumberOfParameters()) + ")" + return
result = "(" + this.descriptorUpTo(this.getNumberOfParameters()) + ")" + return
)
}
@@ -86,19 +86,19 @@ class Callable extends StmtParent, Member, @callable {
n = 0 and result = ""
or
exists(Parameter p | p = this.getParameter(n - 1) |
result = descriptorUpTo(n - 1) + p.getType().getTypeDescriptor()
result = this.descriptorUpTo(n - 1) + p.getType().getTypeDescriptor()
)
}
/** Holds if this callable calls `target`. */
predicate calls(Callable target) { exists(getACallSite(target)) }
predicate calls(Callable target) { exists(this.getACallSite(target)) }
/**
* Holds if this callable calls `target`
* using a `super(...)` constructor call.
*/
predicate callsSuperConstructor(Constructor target) {
getACallSite(target) instanceof SuperConstructorInvocationStmt
this.getACallSite(target) instanceof SuperConstructorInvocationStmt
}
/**
@@ -106,14 +106,14 @@ class Callable extends StmtParent, Member, @callable {
* using a `this(...)` constructor call.
*/
predicate callsThis(Constructor target) {
getACallSite(target) instanceof ThisConstructorInvocationStmt
this.getACallSite(target) instanceof ThisConstructorInvocationStmt
}
/**
* Holds if this callable calls `target`
* using a `super` method call.
*/
predicate callsSuper(Method target) { getACallSite(target) instanceof SuperMethodAccess }
predicate callsSuper(Method target) { this.getACallSite(target) instanceof SuperMethodAccess }
/**
* Holds if this callable calls `c` using
@@ -165,13 +165,13 @@ class Callable extends StmtParent, Member, @callable {
Field getAnAccessedField() { this.accesses(result) }
/** Gets the type of a formal parameter of this callable. */
Type getAParamType() { result = getParameterType(_) }
Type getAParamType() { result = this.getParameterType(_) }
/** Holds if this callable does not have any formal parameters. */
predicate hasNoParameters() { not exists(getAParameter()) }
predicate hasNoParameters() { not exists(this.getAParameter()) }
/** Gets the number of formal parameters of this callable. */
int getNumberOfParameters() { result = count(getAParameter()) }
int getNumberOfParameters() { result = count(this.getAParameter()) }
/** Gets a formal parameter of this callable. */
Parameter getAParameter() { result.getCallable() = this }
@@ -205,7 +205,7 @@ class Callable extends StmtParent, Member, @callable {
*/
pragma[nomagic]
string paramsString() {
exists(int n | n = getNumberOfParameters() |
exists(int n | n = this.getNumberOfParameters() |
n = 0 and result = "()"
or
n > 0 and result = "(" + this.paramUpTo(n - 1) + ")"
@@ -217,9 +217,9 @@ class Callable extends StmtParent, Member, @callable {
* from left to right, up to (and including) the `n`-th parameter.
*/
private string paramUpTo(int n) {
n = 0 and result = getParameterType(0).toString()
n = 0 and result = this.getParameterType(0).toString()
or
n > 0 and result = paramUpTo(n - 1) + ", " + getParameterType(n)
n > 0 and result = this.paramUpTo(n - 1) + ", " + this.getParameterType(n)
}
/**
@@ -234,7 +234,7 @@ class Callable extends StmtParent, Member, @callable {
Exception getAnException() { exceptions(result, _, this) }
/** Gets an exception type that occurs in the `throws` clause of this callable. */
RefType getAThrownExceptionType() { result = getAnException().getType() }
RefType getAThrownExceptionType() { result = this.getAnException().getType() }
/** Gets a call site that references this callable. */
Call getAReference() { result.getCallee() = this }
@@ -285,7 +285,20 @@ private predicate overrides(Method m1, Method m2) {
or
m2.isProtected()
or
m2.isPackageProtected() and t1.getPackage() = t2.getPackage()
m2.isPackageProtected() and
pragma[only_bind_out](t1.getPackage()) = pragma[only_bind_out](t2.getPackage())
)
}
pragma[nomagic]
private predicate overridesCandidateType(RefType tsup, string sig, RefType t, Method m) {
virtualMethodWithSignature(sig, t, m) and
t.extendsOrImplements(tsup)
or
exists(RefType mid |
overridesCandidateType(mid, sig, t, m) and
mid.extendsOrImplements(tsup) and
not virtualMethodWithSignature(sig, mid, _)
)
}
@@ -294,11 +307,10 @@ private predicate overrides(Method m1, Method m2) {
* ignoring any access modifiers. Additionally, this predicate binds
* `t1` to the type declaring `m1` and `t2` to the type declaring `m2`.
*/
pragma[noopt]
cached
predicate overridesIgnoringAccess(Method m1, RefType t1, Method m2, RefType t2) {
exists(string sig |
virtualMethodWithSignature(sig, t1, m1) and
t1.extendsOrImplements+(t2) and
overridesCandidateType(t2, sig, t1, m1) and
virtualMethodWithSignature(sig, t2, m2)
)
}
@@ -392,7 +404,7 @@ class Method extends Callable, @method {
or
// JLS 9.4: Every method declaration in the body of an interface without an
// access modifier is implicitly public.
getDeclaringType() instanceof Interface and
this.getDeclaringType() instanceof Interface and
not this.isPrivate()
or
exists(FunctionalExpr func | func.asMethod() = this)
@@ -413,7 +425,7 @@ class Method extends Callable, @method {
Callable.super.isStrictfp()
or
// JLS 8.1.1.3, JLS 9.1.1.2
getDeclaringType().isStrictfp()
this.getDeclaringType().isStrictfp()
}
/**
@@ -421,8 +433,8 @@ class Method extends Callable, @method {
* nor an initializer method, and hence could be inherited.
*/
predicate isInheritable() {
not isPrivate() and
not (isStatic() and getDeclaringType() instanceof Interface) and
not this.isPrivate() and
not (this.isStatic() and this.getDeclaringType() instanceof Interface) and
not this instanceof InitializerMethod
}
@@ -430,13 +442,13 @@ class Method extends Callable, @method {
* Holds if this method is neither private nor static, and hence
* uses dynamic dispatch.
*/
predicate isVirtual() { not isPrivate() and not isStatic() }
predicate isVirtual() { not this.isPrivate() and not this.isStatic() }
/** Holds if this method can be overridden. */
predicate isOverridable() {
isVirtual() and
not isFinal() and
not getDeclaringType().isFinal()
this.isVirtual() and
not this.isFinal() and
not this.getDeclaringType().isFinal()
}
override string getAPrimaryQlClass() { result = "Method" }
@@ -549,7 +561,7 @@ abstract class InitializerMethod extends Method { }
* field initializations and static initializer blocks.
*/
class StaticInitializer extends InitializerMethod {
StaticInitializer() { hasName("<clinit>") }
StaticInitializer() { this.hasName("<clinit>") }
}
/**
@@ -629,7 +641,7 @@ class Field extends Member, ExprParent, @field, Variable {
or
// JLS 9.3: Every field declaration in the body of an interface is
// implicitly public, static, and final
getDeclaringType() instanceof Interface
this.getDeclaringType() instanceof Interface
}
override predicate isStatic() {

View File

@@ -25,7 +25,7 @@ abstract class Modifiable extends Element {
* abstract, so `isAbstract()` will hold for them even if `hasModifier("abstract")`
* does not.
*/
predicate hasModifier(string m) { modifiers(getAModifier(), m) }
predicate hasModifier(string m) { modifiers(this.getAModifier(), m) }
/** Holds if this element has no modifier. */
predicate hasNoModifier() { not hasModifier(this, _) }
@@ -34,31 +34,31 @@ abstract class Modifiable extends Element {
Modifier getAModifier() { this = result.getElement() }
/** Holds if this element has an `abstract` modifier or is implicitly abstract. */
predicate isAbstract() { hasModifier("abstract") }
predicate isAbstract() { this.hasModifier("abstract") }
/** Holds if this element has a `static` modifier or is implicitly static. */
predicate isStatic() { hasModifier("static") }
predicate isStatic() { this.hasModifier("static") }
/** Holds if this element has a `final` modifier or is implicitly final. */
predicate isFinal() { hasModifier("final") }
predicate isFinal() { this.hasModifier("final") }
/** Holds if this element has a `public` modifier or is implicitly public. */
predicate isPublic() { hasModifier("public") }
predicate isPublic() { this.hasModifier("public") }
/** Holds if this element has a `protected` modifier. */
predicate isProtected() { hasModifier("protected") }
predicate isProtected() { this.hasModifier("protected") }
/** Holds if this element has a `private` modifier or is implicitly private. */
predicate isPrivate() { hasModifier("private") }
predicate isPrivate() { this.hasModifier("private") }
/** Holds if this element has a `volatile` modifier. */
predicate isVolatile() { hasModifier("volatile") }
predicate isVolatile() { this.hasModifier("volatile") }
/** Holds if this element has a `synchronized` modifier. */
predicate isSynchronized() { hasModifier("synchronized") }
predicate isSynchronized() { this.hasModifier("synchronized") }
/** Holds if this element has a `native` modifier. */
predicate isNative() { hasModifier("native") }
predicate isNative() { this.hasModifier("native") }
/** Holds if this element has a `default` modifier. */
predicate isDefault() { this.hasModifier("default") }

View File

@@ -169,27 +169,27 @@ private class PpArrayCreationExpr extends PpAst, ArrayCreationExpr {
override string getPart(int i) {
i = 0 and result = "new "
or
i = 1 and result = baseType()
i = 1 and result = this.baseType()
or
i = 2 + 3 * dimensionIndex() and result = "["
i = 2 + 3 * this.dimensionIndex() and result = "["
or
i = 4 + 3 * dimensionIndex() and result = "]"
i = 4 + 3 * this.dimensionIndex() and result = "]"
or
i = 4 + 3 * exprDims() + [1 .. nonExprDims()] and result = "[]"
i = 4 + 3 * this.exprDims() + [1 .. this.nonExprDims()] and result = "[]"
}
private string baseType() { result = this.getType().(Array).getElementType().toString() }
private int dimensionIndex() { exists(this.getDimension(result)) }
private int exprDims() { result = max(int j | j = 0 or j = 1 + dimensionIndex()) }
private int exprDims() { result = max(int j | j = 0 or j = 1 + this.dimensionIndex()) }
private int nonExprDims() { result = this.getType().(Array).getDimension() - exprDims() }
private int nonExprDims() { result = this.getType().(Array).getDimension() - this.exprDims() }
override PpAst getChild(int i) {
exists(int j | result = this.getDimension(j) and i = 3 + 3 * j)
or
i = 5 + 3 * exprDims() + nonExprDims() and result = this.getInit()
i = 5 + 3 * this.exprDims() + this.nonExprDims() and result = this.getInit()
}
}
@@ -539,27 +539,27 @@ private class PpForStmt extends PpAst, ForStmt {
or
exists(int j | j > 0 and exists(this.getInit(j)) and i = 2 + 2 * j and result = ", ")
or
i = 1 + lastInitIndex() and result = "; "
i = 1 + this.lastInitIndex() and result = "; "
or
i = 3 + lastInitIndex() and result = "; "
i = 3 + this.lastInitIndex() and result = "; "
or
exists(int j |
j > 0 and exists(this.getUpdate(j)) and i = 3 + lastInitIndex() + 2 * j and result = ", "
j > 0 and exists(this.getUpdate(j)) and i = 3 + this.lastInitIndex() + 2 * j and result = ", "
)
or
i = 1 + lastUpdateIndex() and result = ")"
i = 1 + this.lastUpdateIndex() and result = ")"
or
i = 2 + lastUpdateIndex() and result = " " and this.getStmt() instanceof BlockStmt
i = 2 + this.lastUpdateIndex() and result = " " and this.getStmt() instanceof BlockStmt
}
private int lastInitIndex() { result = 3 + 2 * max(int j | exists(this.getInit(j))) }
private int lastUpdateIndex() {
result = 4 + lastInitIndex() + 2 * max(int j | exists(this.getUpdate(j)))
result = 4 + this.lastInitIndex() + 2 * max(int j | exists(this.getUpdate(j)))
}
override predicate newline(int i) {
i = 2 + lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
i = 2 + this.lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
}
override PpAst getChild(int i) {
@@ -567,15 +567,15 @@ private class PpForStmt extends PpAst, ForStmt {
or
exists(int j | result = this.getInit(j) and i = 3 + 2 * j)
or
i = 2 + lastInitIndex() and result = this.getCondition()
i = 2 + this.lastInitIndex() and result = this.getCondition()
or
exists(int j | result = this.getUpdate(j) and i = 4 + lastInitIndex() + 2 * j)
exists(int j | result = this.getUpdate(j) and i = 4 + this.lastInitIndex() + 2 * j)
or
i = 3 + lastUpdateIndex() and result = this.getStmt()
i = 3 + this.lastUpdateIndex() and result = this.getStmt()
}
override predicate indents(int i) {
i = 3 + lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
i = 3 + this.lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
}
}
@@ -654,9 +654,9 @@ private class PpTryStmt extends PpAst, TryStmt {
or
exists(int j | exists(this.getResourceExpr(j)) and i = 3 + 2 * j and result = ";")
or
i = 2 + lastResourceIndex() and result = ") " and exists(this.getAResource())
i = 2 + this.lastResourceIndex() and result = ") " and exists(this.getAResource())
or
i = 1 + lastCatchIndex() and result = " finally " and exists(this.getFinally())
i = 1 + this.lastCatchIndex() and result = " finally " and exists(this.getFinally())
}
private int lastResourceIndex() {
@@ -664,17 +664,17 @@ private class PpTryStmt extends PpAst, TryStmt {
}
private int lastCatchIndex() {
result = 4 + lastResourceIndex() + max(int j | exists(this.getCatchClause(j)) or j = 0)
result = 4 + this.lastResourceIndex() + max(int j | exists(this.getCatchClause(j)) or j = 0)
}
override PpAst getChild(int i) {
exists(int j | i = 2 + 2 * j and result = this.getResource(j))
or
i = 3 + lastResourceIndex() and result = this.getBlock()
i = 3 + this.lastResourceIndex() and result = this.getBlock()
or
exists(int j | i = 4 + lastResourceIndex() + j and result = this.getCatchClause(j))
exists(int j | i = 4 + this.lastResourceIndex() + j and result = this.getCatchClause(j))
or
i = 2 + lastCatchIndex() and result = this.getFinally()
i = 2 + this.lastCatchIndex() and result = this.getFinally()
}
}
@@ -728,11 +728,11 @@ private class PpSwitchCase extends PpAst, SwitchCase {
or
exists(int j | i = 2 * j and j != 0 and result = ", " and exists(this.(ConstCase).getValue(j)))
or
i = 1 + lastConstCaseValueIndex() and result = ":" and not this.isRule()
i = 1 + this.lastConstCaseValueIndex() and result = ":" and not this.isRule()
or
i = 1 + lastConstCaseValueIndex() and result = " -> " and this.isRule()
i = 1 + this.lastConstCaseValueIndex() and result = " -> " and this.isRule()
or
i = 3 + lastConstCaseValueIndex() and result = ";" and exists(this.getRuleExpression())
i = 3 + this.lastConstCaseValueIndex() and result = ";" and exists(this.getRuleExpression())
}
private int lastConstCaseValueIndex() {
@@ -742,9 +742,9 @@ private class PpSwitchCase extends PpAst, SwitchCase {
override PpAst getChild(int i) {
exists(int j | i = 1 + 2 * j and result = this.(ConstCase).getValue(j))
or
i = 2 + lastConstCaseValueIndex() and result = this.getRuleExpression()
i = 2 + this.lastConstCaseValueIndex() and result = this.getRuleExpression()
or
i = 2 + lastConstCaseValueIndex() and result = this.getRuleStatement()
i = 2 + this.lastConstCaseValueIndex() and result = this.getRuleStatement()
}
}

View File

@@ -151,7 +151,7 @@ class PrintAstNode extends TPrintAstNode {
/**
* Gets a child of this node.
*/
final PrintAstNode getAChild() { result = getChild(_) }
final PrintAstNode getAChild() { result = this.getChild(_) }
/**
* Gets the parent of this node, if any.
@@ -169,7 +169,7 @@ class PrintAstNode extends TPrintAstNode {
*/
string getProperty(string key) {
key = "semmle.label" and
result = toString()
result = this.toString()
}
/**
@@ -178,7 +178,7 @@ class PrintAstNode extends TPrintAstNode {
* this.
*/
string getChildEdgeLabel(int childIndex) {
exists(getChild(childIndex)) and
exists(this.getChild(childIndex)) and
result = childIndex.toString()
}
}
@@ -259,7 +259,7 @@ final class AnnotationPartNode extends ExprStmtNode {
override ElementNode getChild(int childIndex) {
result.getElement() =
rank[childIndex](Element ch, string file, int line, int column |
ch = getAnAnnotationChild() and locationSortKeys(ch, file, line, column)
ch = this.getAnAnnotationChild() and locationSortKeys(ch, file, line, column)
|
ch order by file, line, column
)
@@ -352,7 +352,7 @@ private class SingleLocalVarDeclParent extends ExprOrStmt {
LocalVariableDeclExpr getVariable() { result.getParent() = this }
/** Gets the type access of the variable */
Expr getTypeAccess() { result = getVariable().getTypeAccess() }
Expr getTypeAccess() { result = this.getVariable().getTypeAccess() }
}
/**
@@ -460,7 +460,7 @@ final class ClassInterfaceNode extends ElementNode {
childIndex >= 0 and
result.(ElementNode).getElement() =
rank[childIndex](Element e, string file, int line, int column |
e = getADeclaration() and locationSortKeys(e, file, line, column)
e = this.getADeclaration() and locationSortKeys(e, file, line, column)
|
e order by file, line, column
)
@@ -507,7 +507,7 @@ final class CompilationUnitNode extends ElementNode {
childIndex >= 0 and
result.(ElementNode).getElement() =
rank[childIndex](Element e, string file, int line, int column |
e = getADeclaration() and locationSortKeys(e, file, line, column)
e = this.getADeclaration() and locationSortKeys(e, file, line, column)
|
e order by file, line, column
)
@@ -665,7 +665,7 @@ final class GenericTypeNode extends PrintAstNode, TGenericTypeNode {
override Location getLocation() { none() }
override ElementNode getChild(int childIndex) {
result.getElement().(TypeVariable) = ty.getTypeParameter(childIndex)
result.getElement() = ty.getTypeParameter(childIndex)
}
/**
@@ -686,7 +686,7 @@ final class GenericCallableNode extends PrintAstNode, TGenericCallableNode {
override string toString() { result = "(Generic Parameters)" }
override ElementNode getChild(int childIndex) {
result.getElement().(TypeVariable) = c.getTypeParameter(childIndex)
result.getElement() = c.getTypeParameter(childIndex)
}
/**

View File

@@ -55,7 +55,7 @@ abstract private class ReflectiveClassIdentifier extends Expr {
private class ReflectiveClassIdentifierLiteral extends ReflectiveClassIdentifier, TypeLiteral {
override RefType getReflectivelyIdentifiedClass() {
result = getReferencedType().(RefType).getSourceDeclaration()
result = this.getReferencedType().(RefType).getSourceDeclaration()
}
}
@@ -65,21 +65,21 @@ private class ReflectiveClassIdentifierLiteral extends ReflectiveClassIdentifier
class ReflectiveClassIdentifierMethodAccess extends ReflectiveClassIdentifier, MethodAccess {
ReflectiveClassIdentifierMethodAccess() {
// A call to `Class.forName(...)`, from which we can infer `T` in the returned type `Class<T>`.
getCallee().getDeclaringType() instanceof TypeClass and getCallee().hasName("forName")
this.getCallee().getDeclaringType() instanceof TypeClass and this.getCallee().hasName("forName")
or
// A call to `ClassLoader.loadClass(...)`, from which we can infer `T` in the returned type `Class<T>`.
getCallee().getDeclaringType().hasQualifiedName("java.lang", "ClassLoader") and
getCallee().hasName("loadClass")
this.getCallee().getDeclaringType().hasQualifiedName("java.lang", "ClassLoader") and
this.getCallee().hasName("loadClass")
}
/**
* If the argument to this call is a `StringLiteral`, then return that string.
*/
string getTypeName() { result = getArgument(0).(StringLiteral).getRepresentedString() }
string getTypeName() { result = this.getArgument(0).(StringLiteral).getValue() }
override RefType getReflectivelyIdentifiedClass() {
// We only handle cases where the class is specified as a string literal to this call.
result.getQualifiedName() = getTypeName()
result.getQualifiedName() = this.getTypeName()
}
}
@@ -150,7 +150,7 @@ private Type parameterForSubTypes(ParameterizedType type) {
lowerBound = arg.(Wildcard).getLowerBoundType()
|
// `T super Foo` implies that `Foo`, or any super-type of `Foo`, may be represented.
lowerBound.(RefType).getAnAncestor() = result
lowerBound.getAnAncestor() = result
)
)
}
@@ -214,10 +214,10 @@ private predicate expectsEnclosingInstance(RefType r) {
class NewInstance extends MethodAccess {
NewInstance() {
(
getCallee().getDeclaringType() instanceof TypeClass or
getCallee().getDeclaringType() instanceof TypeConstructor
this.getCallee().getDeclaringType() instanceof TypeClass or
this.getCallee().getDeclaringType() instanceof TypeConstructor
) and
getCallee().hasName("newInstance")
this.getCallee().hasName("newInstance")
}
/**
@@ -225,26 +225,26 @@ class NewInstance extends MethodAccess {
* called.
*/
Constructor getInferredConstructor() {
result = getInferredConstructedType().getAConstructor() and
if getCallee().getDeclaringType() instanceof TypeClass
result = this.getInferredConstructedType().getAConstructor() and
if this.getCallee().getDeclaringType() instanceof TypeClass
then result.getNumberOfParameters() = 0
else
if getNumArgument() = 1 and getArgument(0).getType() instanceof Array
if this.getNumArgument() = 1 and this.getArgument(0).getType() instanceof Array
then
// This is a var-args array argument. If array argument is initialized inline, then identify
// the number of arguments specified in the array.
if exists(getArgument(0).(ArrayCreationExpr).getInit())
if exists(this.getArgument(0).(ArrayCreationExpr).getInit())
then
// Count the number of elements in the initializer, and find the matching constructors.
matchConstructorArguments(result,
count(getArgument(0).(ArrayCreationExpr).getInit().getAnInit()))
this.matchConstructorArguments(result,
count(this.getArgument(0).(ArrayCreationExpr).getInit().getAnInit()))
else
// Could be any of the constructors on this class.
any()
else
// No var-args in play, just use the number of arguments to the `newInstance(..)` to determine
// which constructors may be called.
matchConstructorArguments(result, getNumArgument())
this.matchConstructorArguments(result, this.getNumArgument())
}
/**
@@ -273,13 +273,13 @@ class NewInstance extends MethodAccess {
not result instanceof TypeVariable and
(
// If this is called on a `Class<T>` instance, return the inferred type `T`.
result = inferClassParameterType(getQualifier())
result = inferClassParameterType(this.getQualifier())
or
// If this is called on a `Constructor<T>` instance, return the inferred type `T`.
result = inferConstructorParameterType(getQualifier())
result = inferConstructorParameterType(this.getQualifier())
or
// If the result of this is cast to a particular type, then use that type.
result = getCastInferredConstructedTypes()
result = this.getCastInferredConstructedTypes()
)
}
@@ -313,7 +313,7 @@ class ClassMethodAccess extends MethodAccess {
// `TypeVariable`s do not have methods themselves.
not result instanceof TypeVariable and
// If this is called on a `Class<T>` instance, return the inferred type `T`.
result = inferClassParameterType(getQualifier())
result = inferClassParameterType(this.getQualifier())
}
}
@@ -354,13 +354,13 @@ class ReflectiveMethodAccess extends ClassMethodAccess {
if this.getCallee().hasName("getDeclaredMethod")
then
// The method must be declared on the type itself.
result.getDeclaringType() = getInferredClassType()
result.getDeclaringType() = this.getInferredClassType()
else
// The method may be declared on an inferred type or a super-type.
getInferredClassType().inherits(result)
this.getInferredClassType().inherits(result)
) and
// Only consider instances where the method name is provided as a `StringLiteral`.
result.hasName(getArgument(0).(StringLiteral).getRepresentedString())
result.hasName(this.getArgument(0).(StringLiteral).getValue())
}
}
@@ -373,7 +373,9 @@ class ReflectiveAnnotationAccess extends ClassMethodAccess {
/**
* Gets a possible annotation type for this reflective annotation access.
*/
AnnotationType getAPossibleAnnotationType() { result = inferClassParameterType(getArgument(0)) }
AnnotationType getAPossibleAnnotationType() {
result = inferClassParameterType(this.getArgument(0))
}
}
/**
@@ -391,13 +393,13 @@ class ReflectiveFieldAccess extends ClassMethodAccess {
if this.getCallee().hasName("getDeclaredField")
then
// Declared fields must be on the type itself.
result.getDeclaringType() = getInferredClassType()
result.getDeclaringType() = this.getInferredClassType()
else (
// This field must be public, and be inherited by one of the inferred class types.
result.isPublic() and
getInferredClassType().inherits(result)
this.getInferredClassType().inherits(result)
)
) and
result.hasName(getArgument(0).(StringLiteral).getRepresentedString())
result.hasName(this.getArgument(0).(StringLiteral).getValue())
}
}

View File

@@ -71,7 +71,7 @@ class BlockStmt extends Stmt, @block {
int getNumStmt() { result = count(this.getAStmt()) }
/** Gets the last statement in this block. */
Stmt getLastStmt() { result = getStmt(getNumStmt() - 1) }
Stmt getLastStmt() { result = this.getStmt(this.getNumStmt() - 1) }
override string pp() { result = "{ ... }" }
@@ -93,7 +93,7 @@ class SingletonBlock extends BlockStmt {
SingletonBlock() { this.getNumStmt() = 1 }
/** Gets the single statement in this block. */
Stmt getStmt() { result = getStmt(0) }
Stmt getStmt() { result = this.getStmt(0) }
}
/**
@@ -125,7 +125,7 @@ class IfStmt extends ConditionalStmt, @ifstmt {
* Gets the statement that is executed whenever the condition
* of this branch statement evaluates to `true`.
*/
deprecated override Stmt getTrueSuccessor() { result = getThen() }
deprecated override Stmt getTrueSuccessor() { result = this.getThen() }
/** Gets the `else` branch of this `if` statement. */
Stmt getElse() { result.isNthChildOf(this, 2) }
@@ -155,7 +155,7 @@ class ForStmt extends ConditionalStmt, @forstmt {
/** Gets the initializer expression of the loop at the specified (zero-based) position. */
Expr getInit(int index) {
result = getAnInit() and
result = this.getAnInit() and
index = -1 - result.getIndex()
}
@@ -167,7 +167,7 @@ class ForStmt extends ConditionalStmt, @forstmt {
/** Gets the update expression of this loop at the specified (zero-based) position. */
Expr getUpdate(int index) {
result = getAnUpdate() and
result = this.getAnUpdate() and
index = result.getIndex() - 3
}
@@ -178,7 +178,7 @@ class ForStmt extends ConditionalStmt, @forstmt {
* Gets the statement that is executed whenever the condition
* of this branch statement evaluates to true.
*/
deprecated override Stmt getTrueSuccessor() { result = getStmt() }
deprecated override Stmt getTrueSuccessor() { result = this.getStmt() }
/**
* Gets a variable that is used as an iteration variable: it is defined,
@@ -193,12 +193,12 @@ class ForStmt extends ConditionalStmt, @forstmt {
*/
Variable getAnIterationVariable() {
// Check that the variable is assigned to, incremented or decremented in the update expression, and...
exists(Expr update | update = getAnUpdate().getAChildExpr*() |
exists(Expr update | update = this.getAnUpdate().getAChildExpr*() |
update.(UnaryAssignExpr).getExpr() = result.getAnAccess() or
update = result.getAnAssignedValue()
) and
// ...that it is checked or used in the condition.
getCondition().getAChildExpr*() = result.getAnAccess()
this.getCondition().getAChildExpr*() = result.getAnAccess()
}
override string pp() { result = "for (...;...;...) " + this.getStmt().pp() }
@@ -242,7 +242,7 @@ class WhileStmt extends ConditionalStmt, @whilestmt {
* Gets the statement that is executed whenever the condition
* of this branch statement evaluates to true.
*/
deprecated override Stmt getTrueSuccessor() { result = getStmt() }
deprecated override Stmt getTrueSuccessor() { result = this.getStmt() }
override string pp() { result = "while (...) " + this.getStmt().pp() }
@@ -265,7 +265,7 @@ class DoStmt extends ConditionalStmt, @dostmt {
* Gets the statement that is executed whenever the condition
* of this branch statement evaluates to `true`.
*/
deprecated override Stmt getTrueSuccessor() { result = getStmt() }
deprecated override Stmt getTrueSuccessor() { result = this.getStmt() }
override string pp() { result = "do " + this.getStmt().pp() + " while (...)" }
@@ -343,17 +343,17 @@ class TryStmt extends Stmt, @trystmt {
}
/** Gets a resource in this `try` statement, if any. */
ExprParent getAResource() { result = getAResourceDecl() or result = getAResourceExpr() }
ExprParent getAResource() { result = this.getAResourceDecl() or result = this.getAResourceExpr() }
/** Gets the resource at the specified position in this `try` statement. */
ExprParent getResource(int index) {
result = getResourceDecl(index) or result = getResourceExpr(index)
result = this.getResourceDecl(index) or result = this.getResourceExpr(index)
}
/** Gets a resource variable, if any, either from a resource variable declaration or resource expression. */
Variable getAResourceVariable() {
result = getAResourceDecl().getAVariable().getVariable() or
result = getAResourceExpr().getVariable()
result = this.getAResourceDecl().getAVariable().getVariable() or
result = this.getAResourceExpr().getVariable()
}
override string pp() { result = "try " + this.getBlock().pp() + " catch (...)" }
@@ -381,7 +381,7 @@ class CatchClause extends Stmt, @catchclause {
/** Gets a type caught by this `catch` clause. */
RefType getACaughtType() {
exists(Expr ta | ta = getVariable().getTypeAccess() |
exists(Expr ta | ta = this.getVariable().getTypeAccess() |
result = ta.(TypeAccess).getType() or
result = ta.(UnionTypeAccess).getAnAlternative().getType()
)
@@ -411,7 +411,7 @@ class SwitchStmt extends Stmt, @switchstmt {
* Gets a case of this `switch` statement,
* which may be either a normal `case` or a `default`.
*/
SwitchCase getACase() { result = getAConstCase() or result = getDefaultCase() }
SwitchCase getACase() { result = this.getAConstCase() or result = this.getDefaultCase() }
/** Gets a (non-default) `case` of this `switch` statement. */
ConstCase getAConstCase() { result.getParent() = this }
@@ -550,7 +550,7 @@ class ThrowStmt extends Stmt, @throwstmt {
override string getHalsteadID() { result = "ThrowStmt" }
/** Gets the type of the expression thrown by this `throw` statement. */
RefType getThrownExceptionType() { result = getExpr().getType() }
RefType getThrownExceptionType() { result = this.getExpr().getType() }
/**
* Gets the `catch` clause that catches the exception
@@ -559,15 +559,15 @@ class ThrowStmt extends Stmt, @throwstmt {
* provided such a `catch` exists.
*/
CatchClause getLexicalCatchIfAny() {
exists(TryStmt try | try = findEnclosing() and result = catchClauseForThis(try))
exists(TryStmt try | try = this.findEnclosing() and result = this.catchClauseForThis(try))
}
private Stmt findEnclosing() {
result = getEnclosingStmt()
result = this.getEnclosingStmt()
or
exists(Stmt mid |
mid = findEnclosing() and
not exists(this.catchClauseForThis(mid.(TryStmt))) and
mid = this.findEnclosing() and
not exists(this.catchClauseForThis(mid)) and
result = mid.getEnclosingStmt()
)
}
@@ -575,7 +575,7 @@ class ThrowStmt extends Stmt, @throwstmt {
private CatchClause catchClauseForThis(TryStmt try) {
result = try.getACatchClause() and
result.getEnclosingCallable() = this.getEnclosingCallable() and
getExpr().getType().(RefType).hasSupertype*(result.getVariable().getType().(RefType)) and
this.getExpr().getType().(RefType).hasSupertype*(result.getVariable().getType()) and
not this.getEnclosingStmt+() = result
}
@@ -599,7 +599,7 @@ class JumpStmt extends Stmt {
namestrings(result.getLabel(), _, this)
}
private Stmt getLabelTarget() { result = getTargetLabel().getStmt() }
private Stmt getLabelTarget() { result = this.getTargetLabel().getStmt() }
private Stmt getAPotentialTarget() {
this.getEnclosingStmt+() = result and
@@ -613,20 +613,20 @@ class JumpStmt extends Stmt {
private SwitchExpr getSwitchExprTarget() { result = this.(YieldStmt).getParent+() }
private StmtParent getEnclosingTarget() {
result = getSwitchExprTarget()
result = this.getSwitchExprTarget()
or
not exists(getSwitchExprTarget()) and
result = getAPotentialTarget() and
not exists(Stmt other | other = getAPotentialTarget() | other.getEnclosingStmt+() = result)
not exists(this.getSwitchExprTarget()) and
result = this.getAPotentialTarget() and
not exists(Stmt other | other = this.getAPotentialTarget() | other.getEnclosingStmt+() = result)
}
/**
* Gets the statement or `switch` expression that this `break`, `yield` or `continue` jumps to.
*/
StmtParent getTarget() {
result = getLabelTarget()
result = this.getLabelTarget()
or
not exists(getLabelTarget()) and result = getEnclosingTarget()
not exists(this.getLabelTarget()) and result = this.getEnclosingTarget()
}
}
@@ -714,9 +714,9 @@ class ExprStmt extends Stmt, @exprstmt {
/** Holds if this statement represents a field declaration with an initializer. */
predicate isFieldDecl() {
getEnclosingCallable() instanceof InitializerMethod and
this.getEnclosingCallable() instanceof InitializerMethod and
exists(FieldDeclaration fd, Location fdl, Location sl |
fdl = fd.getLocation() and sl = getLocation()
fdl = fd.getLocation() and sl = this.getLocation()
|
fdl.getFile() = sl.getFile() and
fdl.getStartLine() = sl.getStartLine() and
@@ -775,7 +775,7 @@ class LocalVariableDeclStmt extends Stmt, @localvariabledeclstmt {
}
/** Gets an index of a variable declared in this local variable declaration statement. */
int getAVariableIndex() { exists(getVariable(result)) }
int getAVariableIndex() { exists(this.getVariable(result)) }
override string pp() { result = "var ...;" }

View File

@@ -152,15 +152,15 @@ class FormattingCall extends Call {
private Expr getLastArg() {
exists(Expr last | last = this.getArgument(this.getNumArgument() - 1) |
if this.hasExplicitVarargsArray()
then result = last.(ArrayCreationExpr).getInit().getInit(getVarargsCount() - 1)
then result = last.(ArrayCreationExpr).getInit().getInit(this.getVarargsCount() - 1)
else result = last
)
}
/** Holds if this uses the "logger ({})" format syntax and the last argument is a `Throwable`. */
predicate hasTrailingThrowableArgument() {
getSyntax() = TFmtLogger() and
getLastArg().getType().(RefType).getASourceSupertype*() instanceof TypeThrowable
this.getSyntax() = TFmtLogger() and
this.getLastArg().getType().(RefType).getASourceSupertype*() instanceof TypeThrowable
}
/** Gets the argument to this call in the position of the format string */
@@ -171,7 +171,7 @@ class FormattingCall extends Call {
exists(int i |
result = this.getArgument(i) and
i > this.getFormatStringIndex() and
not hasExplicitVarargsArray()
not this.hasExplicitVarargsArray()
)
}
@@ -279,7 +279,7 @@ private predicate formatStringFragment(Expr fmt) {
private predicate formatStringValue(Expr e, string fmtvalue) {
formatStringFragment(e) and
(
e.(StringLiteral).getRepresentedString() = fmtvalue
e.(StringLiteral).getValue() = fmtvalue
or
e.getType() instanceof IntegralType and fmtvalue = "1" // dummy value
or
@@ -318,7 +318,7 @@ private predicate formatStringValue(Expr e, string fmtvalue) {
getprop.hasName("getProperty") and
getprop.getDeclaringType().hasQualifiedName("java.lang", "System") and
getprop.getNumberOfParameters() = 1 and
ma.getAnArgument().(StringLiteral).getRepresentedString() = prop and
ma.getAnArgument().(StringLiteral).getValue() = prop and
(prop = "line.separator" or prop = "file.separator" or prop = "path.separator") and
fmtvalue = "x" // dummy value
)
@@ -433,15 +433,15 @@ private class PrintfFormatString extends FormatString {
override int getMaxFmtSpecIndex() {
result =
max(int ix |
ix = fmtSpecRefersToSpecificIndex(_) or
ix = count(int i | fmtSpecRefersToSequentialIndex(i))
ix = this.fmtSpecRefersToSpecificIndex(_) or
ix = count(int i | this.fmtSpecRefersToSequentialIndex(i))
)
}
override int getASkippedFmtSpecIndex() {
result in [1 .. getMaxFmtSpecIndex()] and
result > count(int i | fmtSpecRefersToSequentialIndex(i)) and
not result = fmtSpecRefersToSpecificIndex(_)
result in [1 .. this.getMaxFmtSpecIndex()] and
result > count(int i | this.fmtSpecRefersToSequentialIndex(i)) and
not result = this.fmtSpecRefersToSpecificIndex(_)
}
private int getFmtSpecRank(int specOffset) {
@@ -449,14 +449,14 @@ private class PrintfFormatString extends FormatString {
}
override int getAnArgUsageOffset(int argNo) {
argNo = fmtSpecRefersToSpecificIndex(result)
argNo = this.fmtSpecRefersToSpecificIndex(result)
or
result = rank[argNo](int i | fmtSpecRefersToSequentialIndex(i))
result = rank[argNo](int i | this.fmtSpecRefersToSequentialIndex(i))
or
fmtSpecRefersToPrevious(result) and
this.fmtSpecRefersToPrevious(result) and
exists(int previousOffset |
getFmtSpecRank(previousOffset) = getFmtSpecRank(result) - 1 and
previousOffset = getAnArgUsageOffset(argNo)
this.getFmtSpecRank(previousOffset) = this.getFmtSpecRank(result) - 1 and
previousOffset = this.getAnArgUsageOffset(argNo)
)
}
}
@@ -479,10 +479,12 @@ private class LoggerFormatString extends FormatString {
private predicate fmtPlaceholder(int i) {
this.charAt(i) = "{" and
this.charAt(i + 1) = "}" and
not true = isUnescapedBackslash(i - 1)
not true = this.isUnescapedBackslash(i - 1)
}
override int getMaxFmtSpecIndex() { result = count(int i | fmtPlaceholder(i)) }
override int getMaxFmtSpecIndex() { result = count(int i | this.fmtPlaceholder(i)) }
override int getAnArgUsageOffset(int argNo) { result = rank[argNo](int i | fmtPlaceholder(i)) }
override int getAnArgUsageOffset(int argNo) {
result = rank[argNo](int i | this.fmtPlaceholder(i))
}
}

View File

@@ -31,7 +31,7 @@ predicate hasSubtype(RefType t, Type sub) {
arraySubtype(t, sub) and t != sub
or
// Type parameter containment for parameterized types.
parContainmentSubtype(t, sub) and t != sub
parContainmentSubtype(t, sub)
or
// Type variables are subtypes of their upper bounds.
typeVarSubtypeBound(t, sub) and t != sub
@@ -59,19 +59,23 @@ private predicate arraySubtype(Array sup, Array sub) {
* )
* ```
* For performance several transformations are made. First, the `forex` is
* written as a loop where `typeArgumentsContain(_, pt, psub, n)` encode that
* the `forex` holds for `i in [0..n]`. Second, the relation is split into two
* cases depending on whether `pt.getNumberOfTypeArguments()` is 1 or 2+, as
* this allows us to unroll the loop and collapse the first two iterations. The
* base case for `typeArgumentsContain` is therefore `n=1` and this allows an
* improved join order implemented by `contains01`.
* written as a loop where `typePrefixContains(ppt, ppsub)` encode that
* `ppt` and `ppsub` are prefixes of `pt` and `ptsub` and that
* the `forex` holds for `i in [0..n-1]` where `n` is the length of the prefixes.
* Second, the recursive case that determines containment of length `n+1`
* prefixes is split into three cases depending on whether there is
* non-reflexive type parameter containment:
* - only in the length `n` prefix,
* - only in the `n`th position,
* - both in the length `n` prefix and the `n`th position.
*/
private predicate parContainmentSubtype(ParameterizedType pt, ParameterizedType psub) {
pt != psub and
typeArgumentsContain(_, pt, psub, pt.getNumberOfTypeArguments() - 1)
or
typeArgumentsContain0(_, pt, psub)
exists(ParameterizedPrefix ppt, ParameterizedPrefix ppsub |
typePrefixContains(ppt, ppsub) and
ppt.equals(pt) and
ppsub.equals(psub)
)
}
/**
@@ -94,100 +98,116 @@ private RefType parameterisationTypeArgumentVarianceCand(
varianceCandidate(t)
}
/**
* Holds if every type argument of `s` (up to `n` with `n >= 1`) contains the
* corresponding type argument of `t`. Both `s` and `t` are constrained to
* being parameterizations of `g`.
*/
pragma[nomagic]
private predicate typeArgumentsContain(
GenericType g, ParameterizedType s, ParameterizedType t, int n
) {
contains01(g, s, t) and n = 1
private newtype TParameterizedPrefix =
TGenericType(GenericType g) or
TTypeParam(ParameterizedPrefix pp, RefType t) { prefixMatches(pp, t, _, _) }
/** Holds if `pp` is a length `n` prefix of `pt`. */
private predicate prefixMatches(ParameterizedPrefix pp, ParameterizedType pt, int n) {
pp = TGenericType(pt.getGenericType()) and n = 0
or
contains(g, s, t, n) and
typeArgumentsContain(g, s, t, n - 1)
}
private predicate typeArgumentsContain0(
GenericType g, ParameterizedType sParm, ParameterizedType tParm
) {
exists(RefType s, RefType t |
containsAux0(g, tParm, s, t) and
s = parameterisationTypeArgument(g, sParm, 0) and
s != t
exists(ParameterizedPrefix pp0, RefType t |
pp = TTypeParam(pp0, t) and prefixMatches(pp0, t, pt, n - 1)
)
}
/**
* Holds if the `n`-th type argument of `sParm` contain the `n`-th type
* argument of `tParm` for both `n = 0` and `n = 1`, where both `sParm` and
* `tParm` are parameterizations of the same generic type `g`.
*
* This is equivalent to
* ```
* contains(g, sParm, tParm, 0) and
* contains(g, sParm, tParm, 1)
* ```
* except `contains` is restricted to only include `n >= 2`.
* Holds if `pp` is a length `n` prefix of `pt` and `t` is the `n`th type
* argument of `pt`.
*/
private predicate contains01(GenericType g, ParameterizedType sParm, ParameterizedType tParm) {
exists(RefType s0, RefType t0, RefType s1, RefType t1 |
contains01Aux0(g, tParm, s0, t0, t1) and
contains01Aux1(g, sParm, s0, s1, t1)
)
}
pragma[nomagic]
private predicate contains01Aux0(
GenericType g, ParameterizedType tParm, RefType s0, RefType t0, RefType t1
) {
typeArgumentContains(g, s0, t0, 0) and
t0 = parameterisationTypeArgument(g, tParm, 0) and
t1 = parameterisationTypeArgument(g, tParm, 1)
}
pragma[nomagic]
private predicate contains01Aux1(
GenericType g, ParameterizedType sParm, RefType s0, RefType s1, RefType t1
) {
typeArgumentContains(g, s1, t1, 1) and
s0 = parameterisationTypeArgumentVarianceCand(g, sParm, 0) and
s1 = parameterisationTypeArgumentVarianceCand(g, sParm, 1)
}
pragma[nomagic]
private predicate containsAux0(GenericType g, ParameterizedType tParm, RefType s, RefType t) {
typeArgumentContains(g, s, t, 0) and
t = parameterisationTypeArgument(g, tParm, 0) and
g.getNumberOfTypeParameters() = 1
private predicate prefixMatches(ParameterizedPrefix pp, RefType t, ParameterizedType pt, int n) {
prefixMatches(pp, pt, n) and
t = pt.getTypeArgument(n)
}
/**
* Holds if the `n`-th type argument of `sParm` contain the `n`-th type
* argument of `tParm`, where both `sParm` and `tParm` are parameterizations of
* the same generic type `g`. The index `n` is restricted to `n >= 2`, the
* cases `n < 2` are handled by `contains01`.
*
* See JLS 4.5.1, Type Arguments of Parameterized Types.
* A prefix of a `ParameterizedType`. This encodes the corresponding
* `GenericType` and the first `n` type arguments where `n` is the prefix
* length.
*/
private predicate contains(GenericType g, ParameterizedType sParm, ParameterizedType tParm, int n) {
exists(RefType s, RefType t |
containsAux(g, tParm, n, s, t) and
s = parameterisationTypeArgumentVarianceCand(g, sParm, n)
private class ParameterizedPrefix extends TParameterizedPrefix {
string toString() { result = "ParameterizedPrefix" }
predicate equals(ParameterizedType pt) { prefixMatches(this, pt, pt.getNumberOfTypeArguments()) }
/** Holds if this prefix has length `n`, applies to `g`, and equals `TTypeParam(pp, t)`. */
predicate split(GenericType g, ParameterizedPrefix pp, RefType t, int n) {
this = TTypeParam(pp, t) and
(
pp = TGenericType(g) and n = 0
or
pp.split(g, _, _, n - 1)
)
}
}
/**
* Holds if every type argument of `pps` contains the corresponding type
* argument of `ppt`. Both `pps` and `ppt` are constrained to be equal-length
* prefixes of parameterizations of the same `GenericType`.
*/
pragma[nomagic]
private predicate typePrefixContains(ParameterizedPrefix pps, ParameterizedPrefix ppt) {
// Let `pps = TTypeParam(pps0, s)` and `ppt = TTypeParam(ppt0, t)`.
// Case 1: pps0 = ppt0 and typeArgumentContains(_, s, t, _)
typePrefixContains_base(pps, ppt)
or
// Case 2: typePrefixContains(pps0, ppt0) and s = t
typePrefixContains_ext_eq(pps, ppt)
or
// Case 3: typePrefixContains(pps0, ppt0) and typeArgumentContains(_, s, t, _)
typePrefixContains_ext_neq(pps, ppt)
}
private predicate typePrefixContains_base(ParameterizedPrefix pps, ParameterizedPrefix ppt) {
exists(ParameterizedPrefix pp, RefType s |
pps = TTypeParam(pp, s) and
typePrefixContainsAux2(ppt, pp, s)
)
}
private predicate typePrefixContains_ext_eq(ParameterizedPrefix pps, ParameterizedPrefix ppt) {
exists(ParameterizedPrefix pps0, ParameterizedPrefix ppt0, RefType t |
typePrefixContains(pragma[only_bind_into](pps0), pragma[only_bind_into](ppt0)) and
pps = TTypeParam(pragma[only_bind_into](pps0), t) and
ppt = TTypeParam(ppt0, t)
)
}
private predicate typePrefixContains_ext_neq(ParameterizedPrefix pps, ParameterizedPrefix ppt) {
exists(ParameterizedPrefix ppt0, RefType s |
typePrefixContainsAux1(pps, ppt0, s) and
typePrefixContainsAux2(ppt, ppt0, s)
)
}
pragma[nomagic]
private predicate containsAux(GenericType g, ParameterizedType tParm, int n, RefType s, RefType t) {
typeArgumentContains(g, s, t, n) and
t = parameterisationTypeArgument(g, tParm, n) and
n >= 2
private predicate typePrefixContainsAux1(
ParameterizedPrefix pps, ParameterizedPrefix ppt0, RefType s
) {
exists(ParameterizedPrefix pps0 |
typePrefixContains(pps0, ppt0) and
pps = TTypeParam(pps0, s) and
s instanceof Wildcard // manual magic, implied by `typeArgumentContains(_, s, t, _)`
)
}
pragma[nomagic]
private predicate typePrefixContainsAux2(
ParameterizedPrefix ppt, ParameterizedPrefix ppt0, RefType s
) {
exists(GenericType g, int n, RefType t |
// Implies `ppt = TTypeParam(ppt0, t)`
ppt.split(g, ppt0, t, n) and
typeArgumentContains(g, s, t, n)
)
}
/**
* Holds if the type argument `s` contains the type argument `t`, where both
* type arguments occur as index `n` in an instantiation of `g`.
*
* The case `s = t` is not included.
*/
pragma[noinline]
private predicate typeArgumentContains(GenericType g, RefType s, RefType t, int n) {
@@ -205,18 +225,18 @@ private predicate typeArgumentContainsAux2(GenericType g, RefType s, RefType t,
* Holds if the type argument `s` contains the type argument `t`, where both
* type arguments occur as index `n` in some parameterized types.
*
* The case `s = t` is not included.
*
* See JLS 4.5.1, Type Arguments of Parameterized Types.
*/
private predicate typeArgumentContainsAux1(RefType s, RefType t, int n) {
exists(int i |
s = parameterisationTypeArgumentVarianceCand(_, _, i) and
t = parameterisationTypeArgument(_, _, n) and
i <= n and
n <= i
|
s = parameterisationTypeArgumentVarianceCand(_, _, pragma[only_bind_into](n)) and
t = parameterisationTypeArgument(_, _, pragma[only_bind_into](n)) and
s != t and
(
exists(RefType tUpperBound | tUpperBound = t.(Wildcard).getUpperBound().getType() |
// ? extends T <= ? extends S if T <: S
hasSubtypeStar(s.(Wildcard).getUpperBound().getType(), tUpperBound)
hasSubtypeStar1(s.(Wildcard).getUpperBound().getType(), tUpperBound)
or
// ? extends T <= ?
s.(Wildcard).isUnconstrained()
@@ -224,7 +244,7 @@ private predicate typeArgumentContainsAux1(RefType s, RefType t, int n) {
or
exists(RefType tLowerBound | tLowerBound = t.(Wildcard).getLowerBound().getType() |
// ? super T <= ? super S if s <: T
hasSubtypeStar(tLowerBound, s.(Wildcard).getLowerBound().getType())
hasSubtypeStar2(tLowerBound, s.(Wildcard).getLowerBound().getType())
or
// ? super T <= ?
s.(Wildcard).isUnconstrained()
@@ -233,14 +253,14 @@ private predicate typeArgumentContainsAux1(RefType s, RefType t, int n) {
wildcardExtendsObject(s)
)
or
// T <= T
s = t
or
// T <= ? extends T
hasSubtypeStar(s.(Wildcard).getUpperBound().getType(), t)
hasSubtypeStar1(s.(Wildcard).getUpperBound().getType(), t)
or
// T <= ? super T
hasSubtypeStar(t, s.(Wildcard).getLowerBound().getType())
hasSubtypeStar2(t, s.(Wildcard).getLowerBound().getType())
// or
// T <= T
// but this case is handled directly in `typePrefixContains`
)
}
@@ -249,12 +269,38 @@ private predicate wildcardExtendsObject(Wildcard wc) {
wc.getUpperBound().getType() instanceof TypeObject
}
private predicate hasSubtypeStar(RefType t, RefType sub) {
sub = t
// manual magic for `hasSubtypeStar1`
private predicate getAWildcardUpperBound(RefType t) {
t = any(Wildcard w).getUpperBound().getType()
}
// manual magic for `hasSubtypeStar2`
private predicate getAWildcardLowerBound(RefType t) {
t = any(Wildcard w).getLowerBound().getType()
}
/**
* Holds if `hasSubtype*(t, sub)`, but manual-magic'ed with `getAWildcardUpperBound(t)`.
*/
pragma[nomagic]
private predicate hasSubtypeStar1(RefType t, RefType sub) {
sub = t and getAWildcardUpperBound(t)
or
hasSubtype(t, sub)
hasSubtype(t, sub) and getAWildcardUpperBound(t)
or
exists(RefType mid | hasSubtypeStar(t, mid) and hasSubtype(mid, sub))
exists(RefType mid | hasSubtypeStar1(t, mid) and hasSubtype(mid, sub))
}
/**
* Holds if `hasSubtype*(t, sub)`, but manual-magic'ed with `getAWildcardLowerBound(sub)`.
*/
pragma[nomagic]
private predicate hasSubtypeStar2(RefType t, RefType sub) {
sub = t and getAWildcardLowerBound(sub)
or
hasSubtype(t, sub) and getAWildcardLowerBound(sub)
or
exists(RefType mid | hasSubtype(t, mid) and hasSubtypeStar2(mid, sub))
}
/** Holds if type `t` declares member `m`. */
@@ -379,7 +425,7 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
}
/** Holds if this type declares any members. */
predicate hasMember() { exists(getAMember()) }
predicate hasMember() { exists(this.getAMember()) }
/** Gets a member declared in this type. */
Member getAMember() { this = result.getDeclaringType() }
@@ -511,7 +557,7 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
this.getSourceDeclaration().inherits(f)
)
or
this.hasMethod(m.(Method), _)
this.hasMethod(m, _)
}
/** Holds if this is a top-level type, which is not nested inside any other types. */
@@ -545,8 +591,10 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
* `java.lang.Thread$State`.
*/
string getQualifiedName() {
exists(string pkgName | pkgName = getPackage().getName() |
if pkgName = "" then result = nestedName() else result = pkgName + "." + nestedName()
exists(string pkgName | pkgName = this.getPackage().getName() |
if pkgName = ""
then result = this.nestedName()
else result = pkgName + "." + this.nestedName()
)
}
@@ -656,7 +704,7 @@ class IntersectionType extends RefType, @class {
/** Gets a textual representation of this type that includes all the intersected types. */
string getLongName() {
result = superType().toString() + concat(" & " + superInterface().toString())
result = this.superType().toString() + concat(" & " + this.superInterface().toString())
}
/** Gets the first bound of this intersection type. */
@@ -690,7 +738,8 @@ class AnonymousClass extends NestedClass {
override string getTypeDescriptor() {
exists(RefType parent | parent = this.getEnclosingType() |
exists(int num |
num = 1 + count(AnonymousClass other | other.rankInParent(parent) < rankInParent(parent))
num =
1 + count(AnonymousClass other | other.rankInParent(parent) < this.rankInParent(parent))
|
exists(string parentWithSemi | parentWithSemi = parent.getTypeDescriptor() |
result = parentWithSemi.prefix(parentWithSemi.length() - 1) + "$" + num + ";"
@@ -760,8 +809,8 @@ class NestedType extends RefType {
/** Gets the nesting depth of this nested type. Top-level types have nesting depth 0. */
int getNestingDepth() {
if getEnclosingType() instanceof NestedType
then result = getEnclosingType().(NestedType).getNestingDepth() + 1
if this.getEnclosingType() instanceof NestedType
then result = this.getEnclosingType().(NestedType).getNestingDepth() + 1
else result = 1
}
@@ -776,7 +825,7 @@ class NestedType extends RefType {
super.isStrictfp()
or
// JLS 8.1.1.3, JLS 9.1.1.2
getEnclosingType().isStrictfp()
this.getEnclosingType().isStrictfp()
}
override predicate isStatic() {
@@ -860,9 +909,9 @@ class ClassOrInterface extends RefType, @classorinterface {
/** Holds if this class or interface is package protected, that is, neither public nor private nor protected. */
predicate isPackageProtected() {
not isPrivate() and
not isProtected() and
not isPublic()
not this.isPrivate() and
not this.isProtected() and
not this.isPublic()
}
}
@@ -948,12 +997,12 @@ class PrimitiveType extends Type, @primitive {
* require an explicit cast.
*/
Literal getADefaultValue() {
getName() = "boolean" and result.getLiteral() = "false"
this.getName() = "boolean" and result.getLiteral() = "false"
or
getName() = "char" and
this.getName() = "char" and
(result.getLiteral() = "'\\0'" or result.getLiteral() = "'\\u0000'")
or
getName().regexpMatch("(float|double|int|short|byte|long)") and
this.getName().regexpMatch("(float|double|int|short|byte|long)") and
result.getLiteral().regexpMatch("0(\\.0)?+[lLfFdD]?+")
}
@@ -1047,7 +1096,7 @@ class EnumType extends Class {
override predicate isFinal() {
// JLS 8.9: An enum declaration is implicitly `final` unless it contains
// at least one enum constant that has a class body.
not getAnEnumConstant().getAnAssignedValue().getType() instanceof AnonymousClass
not this.getAnEnumConstant().getAnAssignedValue().getType() instanceof AnonymousClass
}
}
@@ -1120,7 +1169,10 @@ predicate erasedHaveIntersection(RefType t1, RefType t2) {
t2 = erase(_)
}
/** An integral type, which may be either a primitive or a boxed type. */
/**
* An integral type, which may be either a primitive or a boxed type.
* This includes the types `char` and `Character`.
*/
class IntegralType extends Type {
IntegralType() {
exists(string name |

View File

@@ -38,11 +38,12 @@ class TearDownMethod extends Method {
private class TestRelatedAnnotation extends Annotation {
TestRelatedAnnotation() {
this.getType().getPackage().hasName("org.testng.annotations") or
this.getType().getPackage().hasName("org.junit") or
this.getType().getPackage().hasName("org.junit.runner") or
this.getType().getPackage().hasName("org.junit.jupiter.api") or
this.getType().getPackage().hasName("org.junit.jupiter.params")
this.getType()
.getPackage()
.hasName([
"org.testng.annotations", "org.junit", "org.junit.runner", "org.junit.jupiter.api",
"org.junit.jupiter.params"
])
}
}
@@ -115,7 +116,7 @@ class JUnitJupiterTestMethod extends Method {
* A JUnit `@Ignore` annotation.
*/
class JUnitIgnoreAnnotation extends Annotation {
JUnitIgnoreAnnotation() { getType().hasQualifiedName("org.junit", "Ignore") }
JUnitIgnoreAnnotation() { this.getType().hasQualifiedName("org.junit", "Ignore") }
}
/**
@@ -124,7 +125,7 @@ class JUnitIgnoreAnnotation extends Annotation {
*/
class JUnitIgnoredMethod extends Method {
JUnitIgnoredMethod() {
getAnAnnotation() instanceof JUnitIgnoreAnnotation
this.getAnAnnotation() instanceof JUnitIgnoreAnnotation
or
exists(Class c | c = this.getDeclaringType() |
c.getAnAnnotation() instanceof JUnitIgnoreAnnotation
@@ -136,14 +137,14 @@ class JUnitIgnoredMethod extends Method {
* An annotation in TestNG.
*/
class TestNGAnnotation extends Annotation {
TestNGAnnotation() { getType().getPackage().hasName("org.testng.annotations") }
TestNGAnnotation() { this.getType().getPackage().hasName("org.testng.annotations") }
}
/**
* An annotation of type `org.test.ng.annotations.Test`.
*/
class TestNGTestAnnotation extends TestNGAnnotation {
TestNGTestAnnotation() { getType().hasName("Test") }
TestNGTestAnnotation() { this.getType().hasName("Test") }
}
/**
@@ -158,13 +159,13 @@ class TestNGTestMethod extends Method {
*/
TestNGDataProviderMethod getADataProvider() {
exists(TestNGTestAnnotation testAnnotation |
testAnnotation = getAnAnnotation() and
testAnnotation = this.getAnAnnotation() and
// The data provider must have the same name as the referenced data provider
result.getDataProviderName() =
testAnnotation.getValue("dataProvider").(StringLiteral).getRepresentedString()
testAnnotation.getValue("dataProvider").(StringLiteral).getValue()
|
// Either the data provider should be on the current class, or a supertype
getDeclaringType().getAnAncestor() = result.getDeclaringType()
this.getDeclaringType().getAnAncestor() = result.getDeclaringType()
or
// Or the data provider class should be declared
result.getDeclaringType() =
@@ -190,14 +191,14 @@ class TestMethod extends Method {
* A TestNG annotation used to mark a method that runs "before".
*/
class TestNGBeforeAnnotation extends TestNGAnnotation {
TestNGBeforeAnnotation() { getType().getName().matches("Before%") }
TestNGBeforeAnnotation() { this.getType().getName().matches("Before%") }
}
/**
* A TestNG annotation used to mark a method that runs "after".
*/
class TestNGAfterAnnotation extends TestNGAnnotation {
TestNGAfterAnnotation() { getType().getName().matches("After%") }
TestNGAfterAnnotation() { this.getType().getName().matches("After%") }
}
/**
@@ -205,7 +206,7 @@ class TestNGAfterAnnotation extends TestNGAnnotation {
* them as data provider methods for TestNG.
*/
class TestNGDataProviderAnnotation extends TestNGAnnotation {
TestNGDataProviderAnnotation() { getType().hasName("DataProvider") }
TestNGDataProviderAnnotation() { this.getType().hasName("DataProvider") }
}
/**
@@ -213,7 +214,7 @@ class TestNGDataProviderAnnotation extends TestNGAnnotation {
* them as factory methods for TestNG.
*/
class TestNGFactoryAnnotation extends TestNGAnnotation {
TestNGFactoryAnnotation() { getType().hasName("Factory") }
TestNGFactoryAnnotation() { this.getType().hasName("Factory") }
}
/**
@@ -221,13 +222,13 @@ class TestNGFactoryAnnotation extends TestNGAnnotation {
* which listeners apply to them.
*/
class TestNGListenersAnnotation extends TestNGAnnotation {
TestNGListenersAnnotation() { getType().hasName("Listeners") }
TestNGListenersAnnotation() { this.getType().hasName("Listeners") }
/**
* Gets a listener defined in this annotation.
*/
TestNGListenerImpl getAListener() {
result = getAValue("value").(TypeLiteral).getReferencedType()
result = this.getAValue("value").(TypeLiteral).getReferencedType()
}
}
@@ -235,7 +236,7 @@ class TestNGListenersAnnotation extends TestNGAnnotation {
* A concrete implementation class of one or more of the TestNG listener interfaces.
*/
class TestNGListenerImpl extends Class {
TestNGListenerImpl() { getAnAncestor().hasQualifiedName("org.testng", "ITestNGListener") }
TestNGListenerImpl() { this.getAnAncestor().hasQualifiedName("org.testng", "ITestNGListener") }
}
/**
@@ -246,18 +247,18 @@ class TestNGListenerImpl extends Class {
* an instance of a particular value when running a test method.
*/
class TestNGDataProviderMethod extends Method {
TestNGDataProviderMethod() { getAnAnnotation() instanceof TestNGDataProviderAnnotation }
TestNGDataProviderMethod() { this.getAnAnnotation() instanceof TestNGDataProviderAnnotation }
/**
* Gets the name associated with this data provider.
*/
string getDataProviderName() {
result =
getAnAnnotation()
this.getAnAnnotation()
.(TestNGDataProviderAnnotation)
.getValue("name")
.(StringLiteral)
.getRepresentedString()
.getValue()
}
}
@@ -268,7 +269,7 @@ class TestNGDataProviderMethod extends Method {
* This factory callable is used to generate instances of parameterized test classes.
*/
class TestNGFactoryCallable extends Callable {
TestNGFactoryCallable() { getAnAnnotation() instanceof TestNGFactoryAnnotation }
TestNGFactoryCallable() { this.getAnAnnotation() instanceof TestNGFactoryAnnotation }
}
/**
@@ -276,7 +277,7 @@ class TestNGFactoryCallable extends Callable {
*/
class ParameterizedJUnitTest extends Class {
ParameterizedJUnitTest() {
getAnAnnotation()
this.getAnAnnotation()
.(RunWithAnnotation)
.getRunner()
.(Class)
@@ -289,7 +290,7 @@ class ParameterizedJUnitTest extends Class {
*/
class JUnitCategoryAnnotation extends Annotation {
JUnitCategoryAnnotation() {
getType().hasQualifiedName("org.junit.experimental.categories", "Category")
this.getType().hasQualifiedName("org.junit.experimental.categories", "Category")
}
/**
@@ -297,7 +298,7 @@ class JUnitCategoryAnnotation extends Annotation {
*/
Type getACategory() {
exists(TypeLiteral literal, Expr value |
value = getValue("value") and
value = this.getValue("value") and
(
literal = value or
literal = value.(ArrayCreationExpr).getInit().getAnInit()
@@ -313,7 +314,7 @@ class JUnitCategoryAnnotation extends Annotation {
*/
class JUnitTheoryTest extends Class {
JUnitTheoryTest() {
getAnAnnotation()
this.getAnAnnotation()
.(RunWithAnnotation)
.getRunner()
.(Class)

View File

@@ -47,12 +47,12 @@ class LocalVariableDecl extends @localvar, LocalScopeVariable {
override Callable getCallable() { result = this.getParent().getEnclosingCallable() }
/** Gets the callable in which this declaration occurs. */
Callable getEnclosingCallable() { result = getCallable() }
Callable getEnclosingCallable() { result = this.getCallable() }
override string toString() { result = this.getType().getName() + " " + this.getName() }
/** Gets the initializer expression of this local variable declaration. */
override Expr getInitializer() { result = getDeclExpr().getInit() }
override Expr getInitializer() { result = this.getDeclExpr().getInit() }
override string getAPrimaryQlClass() { result = "LocalVariableDecl" }
}
@@ -63,7 +63,7 @@ class Parameter extends Element, @param, LocalScopeVariable {
override Type getType() { params(this, result, _, _, _) }
/** Holds if the parameter is never assigned a value in the body of the callable. */
predicate isEffectivelyFinal() { not exists(getAnAssignedValue()) }
predicate isEffectivelyFinal() { not exists(this.getAnAssignedValue()) }
/** Gets the (zero-based) index of this formal parameter. */
int getPosition() { params(this, _, result, _, _) }
@@ -87,8 +87,8 @@ class Parameter extends Element, @param, LocalScopeVariable {
* Varargs parameters will have no results for this method.
*/
Expr getAnArgument() {
not isVarargs() and
result = getACallArgument(getPosition())
not this.isVarargs() and
result = this.getACallArgument(this.getPosition())
}
pragma[noinline]

View File

@@ -2,9 +2,9 @@ import java
/** A subclass of `PrimitiveType` with width-based ordering methods. */
class OrdPrimitiveType extends PrimitiveType {
predicate widerThan(OrdPrimitiveType that) { getWidthRank() > that.getWidthRank() }
predicate widerThan(OrdPrimitiveType that) { this.getWidthRank() > that.getWidthRank() }
predicate widerThanOrEqualTo(OrdPrimitiveType that) { getWidthRank() >= that.getWidthRank() }
predicate widerThanOrEqualTo(OrdPrimitiveType that) { this.getWidthRank() >= that.getWidthRank() }
OrdPrimitiveType maxType(OrdPrimitiveType that) {
this.widerThan(that) and result = this

View File

@@ -25,13 +25,13 @@ class BasicBlock extends ControlFlowNode {
/** Gets an immediate successor of this basic block. */
cached
BasicBlock getABBSuccessor() { result = getLastNode().getASuccessor() }
BasicBlock getABBSuccessor() { result = this.getLastNode().getASuccessor() }
/** Gets an immediate predecessor of this basic block. */
BasicBlock getABBPredecessor() { result.getABBSuccessor() = this }
/** Gets a control-flow node contained in this basic block. */
ControlFlowNode getANode() { result = getNode(_) }
ControlFlowNode getANode() { result = this.getNode(_) }
/** Gets the control-flow node at a specific (zero-indexed) position in this basic block. */
cached
@@ -39,7 +39,7 @@ class BasicBlock extends ControlFlowNode {
result = this and pos = 0
or
exists(ControlFlowNode mid, int mid_pos | pos = mid_pos + 1 |
getNode(mid_pos) = mid and
this.getNode(mid_pos) = mid and
mid.getASuccessor() = result and
not result instanceof BasicBlock
)
@@ -49,11 +49,11 @@ class BasicBlock extends ControlFlowNode {
ControlFlowNode getFirstNode() { result = this }
/** Gets the last control-flow node in this basic block. */
ControlFlowNode getLastNode() { result = getNode(length() - 1) }
ControlFlowNode getLastNode() { result = this.getNode(this.length() - 1) }
/** Gets the number of control-flow nodes contained in this basic block. */
cached
int length() { result = strictcount(getANode()) }
int length() { result = strictcount(this.getANode()) }
/** Holds if this basic block strictly dominates `node`. */
predicate bbStrictlyDominates(BasicBlock node) { bbStrictlyDominates(this, node) }

View File

@@ -12,13 +12,13 @@ import semmle.code.java.controlflow.Guards
*/
class ConstantField extends Field {
ConstantField() {
getType() instanceof ImmutableType and
this.getType() instanceof ImmutableType and
// Assigned once
count(getAnAssignedValue()) = 1 and
count(this.getAnAssignedValue()) = 1 and
// And that assignment is either in the appropriate initializer, or, for instance fields on
// classes with one constructor, in the constructor.
forall(FieldWrite fa | fa = getAnAccess() |
if isStatic()
forall(FieldWrite fa | fa = this.getAnAccess() |
if this.isStatic()
then fa.getEnclosingCallable() instanceof StaticInitializer
else (
// Defined in the instance initializer.
@@ -26,7 +26,7 @@ class ConstantField extends Field {
or
// It can be defined in the constructor if there is only one constructor.
fa.getEnclosingCallable() instanceof Constructor and
count(getDeclaringType().getAConstructor()) = 1
count(this.getDeclaringType().getAConstructor()) = 1
)
)
}
@@ -36,7 +36,7 @@ class ConstantField extends Field {
*
* Note: although this value is constant, we may not be able to statically determine the value.
*/
ConstantExpr getConstantValue() { result = getAnAssignedValue() }
ConstantExpr getConstantValue() { result = this.getAnAssignedValue() }
}
/**
@@ -162,18 +162,18 @@ class ConstSwitchStmt extends SwitchStmt {
/** Gets the `ConstCase` that matches, if any. */
ConstCase getMatchingConstCase() {
result = getAConstCase() and
result = this.getAConstCase() and
// Only handle the int case for now
result.getValue().(ConstantExpr).getIntValue() = getExpr().(ConstantExpr).getIntValue()
result.getValue().(ConstantExpr).getIntValue() = this.getExpr().(ConstantExpr).getIntValue()
}
/** Gets the matching case, if it can be deduced. */
SwitchCase getMatchingCase() {
// Must be a value we can deduce
exists(getExpr().(ConstantExpr).getIntValue()) and
if exists(getMatchingConstCase())
then result = getMatchingConstCase()
else result = getDefaultCase()
exists(this.getExpr().(ConstantExpr).getIntValue()) and
if exists(this.getMatchingConstCase())
then result = this.getMatchingConstCase()
else result = this.getDefaultCase()
}
/**
@@ -184,8 +184,8 @@ class ConstSwitchStmt extends SwitchStmt {
SwitchCase getAFailingCase() {
exists(SwitchCase matchingCase |
// We must have found the matching case, otherwise we can't deduce which cases are not matched
matchingCase = getMatchingCase() and
result = getACase() and
matchingCase = this.getMatchingCase() and
result = this.getACase() and
result != matchingCase
)
}
@@ -208,7 +208,7 @@ class UnreachableBasicBlock extends BasicBlock {
or
// This block is not reachable in the CFG, and is not a callable, a body of a callable, an
// expression in an annotation, an expression in an assert statement, or a catch clause.
forall(BasicBlock bb | bb = getABBPredecessor() | bb instanceof UnreachableBasicBlock) and
forall(BasicBlock bb | bb = this.getABBPredecessor() | bb instanceof UnreachableBasicBlock) and
not exists(Callable c | c.getBody() = this) and
not this instanceof Callable and
not exists(Annotation a | a.getAChildExpr*() = this) and
@@ -231,12 +231,12 @@ class UnreachableBasicBlock extends BasicBlock {
* An unreachable expression is an expression contained in an `UnreachableBasicBlock`.
*/
class UnreachableExpr extends Expr {
UnreachableExpr() { getBasicBlock() instanceof UnreachableBasicBlock }
UnreachableExpr() { this.getBasicBlock() instanceof UnreachableBasicBlock }
}
/**
* An unreachable statement is a statement contained in an `UnreachableBasicBlock`.
*/
class UnreachableStmt extends Stmt {
UnreachableStmt() { getBasicBlock() instanceof UnreachableBasicBlock }
UnreachableStmt() { this.getBasicBlock() instanceof UnreachableBasicBlock }
}

View File

@@ -17,16 +17,11 @@ import semmle.code.java.controlflow.UnreachableBlocks
class ExcludeDebuggingProfilingLogging extends ExcludedConstantField {
ExcludeDebuggingProfilingLogging() {
exists(string validFieldName |
validFieldName = "debug" or
validFieldName = "profiling" or
validFieldName = "profile" or
validFieldName = "time" or
validFieldName = "verbose" or
validFieldName = "report" or
validFieldName = "dbg" or
validFieldName = "timing" or
validFieldName = "assert" or
validFieldName = "log"
validFieldName =
[
"debug", "profiling", "profile", "time", "verbose", "report", "dbg", "timing", "assert",
"log"
]
|
getName().regexpMatch(".*(?i)" + validFieldName + ".*")
) and

View File

@@ -79,9 +79,12 @@ private module Frameworks {
private import internal.ContainerFlow
private import semmle.code.java.frameworks.android.Android
private import semmle.code.java.frameworks.android.Intent
private import semmle.code.java.frameworks.android.Slice
private import semmle.code.java.frameworks.android.SQLite
private import semmle.code.java.frameworks.android.XssSinks
private import semmle.code.java.frameworks.ApacheHttp
private import semmle.code.java.frameworks.apache.Collections
private import semmle.code.java.frameworks.apache.IO
private import semmle.code.java.frameworks.apache.Lang
private import semmle.code.java.frameworks.Flexjson
private import semmle.code.java.frameworks.guava.Guava
@@ -95,6 +98,8 @@ private module Frameworks {
private import semmle.code.java.frameworks.Optional
private import semmle.code.java.frameworks.Stream
private import semmle.code.java.frameworks.Strings
private import semmle.code.java.frameworks.ratpack.Ratpack
private import semmle.code.java.frameworks.ratpack.RatpackExec
private import semmle.code.java.frameworks.spring.SpringCache
private import semmle.code.java.frameworks.spring.SpringHttp
private import semmle.code.java.frameworks.spring.SpringUtil
@@ -104,6 +109,7 @@ private module Frameworks {
private import semmle.code.java.frameworks.spring.SpringBeans
private import semmle.code.java.frameworks.spring.SpringWebMultipart
private import semmle.code.java.frameworks.spring.SpringWebUtil
private import semmle.code.java.security.AndroidIntentRedirection
private import semmle.code.java.security.ResponseSplitting
private import semmle.code.java.security.InformationLeak
private import semmle.code.java.security.GroovyInjection
@@ -114,9 +120,6 @@ private module Frameworks {
private import semmle.code.java.security.OgnlInjection
private import semmle.code.java.security.XPath
private import semmle.code.java.security.XsltInjection
private import semmle.code.java.frameworks.android.Android
private import semmle.code.java.frameworks.android.Slice
private import semmle.code.java.frameworks.android.SQLite
private import semmle.code.java.frameworks.Jdbc
private import semmle.code.java.frameworks.SpringJdbc
private import semmle.code.java.frameworks.MyBatis
@@ -321,33 +324,11 @@ private predicate summaryModelCsv(string row) {
"org.apache.commons.codec;BinaryDecoder;true;decode;(byte[]);;Argument[0];ReturnValue;taint",
"org.apache.commons.codec;StringEncoder;true;encode;(String);;Argument[0];ReturnValue;taint",
"org.apache.commons.codec;StringDecoder;true;decode;(String);;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;buffer;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;readLines;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toBufferedInputStream;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toBufferedReader;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toByteArray;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toCharArray;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toInputStream;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toString;;;Argument[0];ReturnValue;taint",
"java.net;URLDecoder;false;decode;;;Argument[0];ReturnValue;taint",
"java.net;URI;false;create;;;Argument[0];ReturnValue;taint",
"javax.xml.transform.sax;SAXSource;false;sourceToInputSource;;;Argument[0];ReturnValue;taint",
// arg to arg
"java.lang;System;false;arraycopy;;;Argument[0];Argument[2];taint",
"org.apache.commons.io;IOUtils;false;copy;;;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;copyLarge;;;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;read;;;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,byte[]);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,ByteBuffer);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(ReadableByteChannel,ByteBuffer);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(Reader,char[]);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(Reader,char[],int,int);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;write;;;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;writeChunked;;;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;writeLines;;;Argument[0];Argument[2];taint",
"org.apache.commons.io;IOUtils;false;writeLines;;;Argument[1];Argument[2];taint",
// constructor flow
"java.io;File;false;File;;;Argument[0];Argument[-1];taint",
"java.io;File;false;File;;;Argument[1];Argument[-1];taint",
@@ -372,7 +353,11 @@ private predicate summaryModelCsv(string row) {
"java.io;StringReader;false;StringReader;;;Argument[0];Argument[-1];taint",
"java.io;CharArrayReader;false;CharArrayReader;;;Argument[0];Argument[-1];taint",
"java.io;BufferedReader;false;BufferedReader;;;Argument[0];Argument[-1];taint",
"java.io;InputStreamReader;false;InputStreamReader;;;Argument[0];Argument[-1];taint"
"java.io;InputStreamReader;false;InputStreamReader;;;Argument[0];Argument[-1];taint",
"java.io;OutputStream;true;write;(byte[]);;Argument[0];Argument[-1];taint",
"java.io;OutputStream;true;write;(byte[],int,int);;Argument[0];Argument[-1];taint",
"java.io;OutputStream;true;write;(int);;Argument[0];Argument[-1];taint",
"java.io;FilterOutputStream;true;FilterOutputStream;(OutputStream);;Argument[0];Argument[-1];taint"
]
}

View File

@@ -45,8 +45,8 @@ private class RmiMethodParameterSource extends RemoteFlowSource {
exists(RemoteCallableMethod method |
method.getAParameter() = this.asParameter() and
(
getType() instanceof PrimitiveType or
getType() instanceof TypeString
this.getType() instanceof PrimitiveType or
this.getType() instanceof TypeString
)
)
}

View File

@@ -11,6 +11,7 @@ private import semmle.code.java.dataflow.DataFlow
*/
private module Frameworks {
private import semmle.code.java.frameworks.jackson.JacksonSerializability
private import semmle.code.java.frameworks.android.AsyncTask
private import semmle.code.java.frameworks.android.Intent
private import semmle.code.java.frameworks.android.SQLite
private import semmle.code.java.frameworks.Guice
@@ -64,6 +65,20 @@ class AdditionalTaintStep extends Unit {
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
/**
* A unit class for adding additional value steps.
*
* Extend this class to add additional value-preserving steps that should apply
* to all data flow configurations.
*/
class AdditionalValueStep extends Unit {
/**
* Holds if the step from `node1` to `node2` is a value-preserving step and
* should apply to all data flow configurations.
*/
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
/**
* A method or constructor that preserves taint.
*

View File

@@ -97,7 +97,7 @@ class SsaSourceVariable extends TSsaSourceVariable {
else result = c.getName() + "(..)." + v.getName()
)
or
result = this.(SsaSourceField).ppQualifier() + "." + getVariable().toString()
result = this.(SsaSourceField).ppQualifier() + "." + this.getVariable().toString()
}
/**
@@ -117,7 +117,7 @@ class SsaSourceVariable extends TSsaSourceVariable {
Location getLocation() {
exists(LocalScopeVariable v | this = TLocalVar(_, v) and result = v.getLocation())
or
this instanceof SsaSourceField and result = getFirstAccess().getLocation()
this instanceof SsaSourceField and result = this.getFirstAccess().getLocation()
}
/** Gets the type of this variable. */
@@ -140,7 +140,7 @@ class SsaSourceField extends SsaSourceVariable {
}
/** Gets the field corresponding to this named field. */
Field getField() { result = getVariable() }
Field getField() { result = this.getVariable() }
/** Gets a string representation of the qualifier. */
string ppQualifier() {
@@ -155,8 +155,8 @@ class SsaSourceField extends SsaSourceVariable {
/** Holds if the field itself or any of the fields part of the qualifier are volatile. */
predicate isVolatile() {
getField().isVolatile() or
getQualifier().(SsaSourceField).isVolatile()
this.getField().isVolatile() or
this.getQualifier().(SsaSourceField).isVolatile()
}
}
@@ -932,10 +932,10 @@ class SsaVariable extends TSsaVariable {
string toString() { none() }
/** Gets the source location for this element. */
Location getLocation() { result = getCFGNode().getLocation() }
Location getLocation() { result = this.getCFGNode().getLocation() }
/** Gets the `BasicBlock` in which this SSA variable is defined. */
BasicBlock getBasicBlock() { result = getCFGNode().getBasicBlock() }
BasicBlock getBasicBlock() { result = this.getCFGNode().getBasicBlock() }
/** Gets an access of this SSA variable. */
RValue getAUse() {
@@ -989,14 +989,16 @@ class SsaUpdate extends SsaVariable {
/** An SSA variable that is defined by a `VariableUpdate`. */
class SsaExplicitUpdate extends SsaUpdate, TSsaCertainUpdate {
SsaExplicitUpdate() {
exists(VariableUpdate upd | upd = this.getCFGNode() and getDestVar(upd) = getSourceVariable())
exists(VariableUpdate upd |
upd = this.getCFGNode() and getDestVar(upd) = this.getSourceVariable()
)
}
override string toString() { result = "SSA def(" + getSourceVariable() + ")" }
override string toString() { result = "SSA def(" + this.getSourceVariable() + ")" }
/** Gets the `VariableUpdate` defining the SSA variable. */
VariableUpdate getDefiningExpr() {
result = this.getCFGNode() and getDestVar(result) = getSourceVariable()
result = this.getCFGNode() and getDestVar(result) = this.getSourceVariable()
}
}
@@ -1010,22 +1012,22 @@ class SsaImplicitUpdate extends SsaUpdate {
SsaImplicitUpdate() { not this instanceof SsaExplicitUpdate }
override string toString() {
result = "SSA impl upd[" + getKind() + "](" + getSourceVariable() + ")"
result = "SSA impl upd[" + this.getKind() + "](" + this.getSourceVariable() + ")"
}
private string getKind() {
this = TSsaUntracked(_, _) and result = "untracked"
or
certainVariableUpdate(getSourceVariable().getQualifier(), getCFGNode(), _, _) and
certainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCFGNode(), _, _) and
result = "explicit qualifier"
or
if uncertainVariableUpdate(getSourceVariable().getQualifier(), getCFGNode(), _, _)
if uncertainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCFGNode(), _, _)
then
if exists(getANonLocalUpdate())
if exists(this.getANonLocalUpdate())
then result = "nonlocal + nonlocal qualifier"
else result = "nonlocal qualifier"
else (
exists(getANonLocalUpdate()) and result = "nonlocal"
exists(this.getANonLocalUpdate()) and result = "nonlocal"
)
}
@@ -1034,9 +1036,9 @@ class SsaImplicitUpdate extends SsaUpdate {
*/
FieldWrite getANonLocalUpdate() {
exists(SsaSourceField f, Callable setter |
f = getSourceVariable() and
f = this.getSourceVariable() and
relevantFieldUpdate(setter, f.getField(), result) and
updatesNamedField(getCFGNode(), f, setter)
updatesNamedField(this.getCFGNode(), f, setter)
)
}
@@ -1049,8 +1051,8 @@ class SsaImplicitUpdate extends SsaUpdate {
*/
predicate assignsUnknownValue() {
this = TSsaUntracked(_, _) or
certainVariableUpdate(getSourceVariable().getQualifier(), getCFGNode(), _, _) or
uncertainVariableUpdate(getSourceVariable().getQualifier(), getCFGNode(), _, _)
certainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCFGNode(), _, _) or
uncertainVariableUpdate(this.getSourceVariable().getQualifier(), this.getCFGNode(), _, _)
}
}
@@ -1072,30 +1074,31 @@ class SsaUncertainImplicitUpdate extends SsaImplicitUpdate, TSsaUncertainUpdate
* includes initial values of parameters, fields, and closure variables.
*/
class SsaImplicitInit extends SsaVariable, TSsaEntryDef {
override string toString() { result = "SSA init(" + getSourceVariable() + ")" }
override string toString() { result = "SSA init(" + this.getSourceVariable() + ")" }
/** Holds if this is a closure variable that captures the value of `capturedvar`. */
predicate captures(SsaVariable capturedvar) {
ssaDefReachesCapture(_, capturedvar, getSourceVariable())
ssaDefReachesCapture(_, capturedvar, this.getSourceVariable())
}
/**
* Holds if the SSA variable is a parameter defined by its initial value in the callable.
*/
predicate isParameterDefinition(Parameter p) {
getSourceVariable() = TLocalVar(p.getCallable(), p) and p.getCallable().getBody() = getCFGNode()
this.getSourceVariable() = TLocalVar(p.getCallable(), p) and
p.getCallable().getBody() = this.getCFGNode()
}
}
/** An SSA phi node. */
class SsaPhiNode extends SsaVariable, TSsaPhiNode {
override string toString() { result = "SSA phi(" + getSourceVariable() + ")" }
override string toString() { result = "SSA phi(" + this.getSourceVariable() + ")" }
/** Gets an input to the phi node defining the SSA variable. */
SsaVariable getAPhiInput() {
exists(BasicBlock phiPred, TrackedVar v |
v = getSourceVariable() and
getCFGNode().(BasicBlock).getABBPredecessor() = phiPred and
v = this.getSourceVariable() and
this.getCFGNode().(BasicBlock).getABBPredecessor() = phiPred and
ssaDefReachesEndOfBlock(v, result, phiPred)
)
}

View File

@@ -0,0 +1,178 @@
/**
* Provides classes and predicates for identifying expressions that may be appended to an interesting prefix.
*
* To use this library, extend the abstract class `InterestingPrefix` to have the library identify expressions that
* may be appended to it, then check `InterestingPrefix.getAnAppendedExpression(Expr)` to get your results.
*
* For example, to identify expressions that may follow "foo:" in some string, we could define:
*
* ```
* private class FooPrefix extends InterestingPrefix {
* int offset;
* FooPrefix() { this.getStringValue().substring("foo:") = offset };
* override int getOffset() { result = offset }
* };
*
* predicate mayFollowFoo(Expr e) { e = any(FooPrefix fp).getAnAppendedExpression() }
* ```
*
* This will identify all the `suffix` expressions in contexts such as:
*
* ```
* "foo:" + suffix1
* "barfoo:" + suffix2
* stringBuilder.append("foo:").append(suffix3);
* String.format("%sfoo:%s", notSuffix, suffix4);
* ```
*/
import java
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.StringFormat
/**
* A string constant that contains a prefix whose possibly-appended strings are
* returned by `getAnAppendedExpression`.
*
* Extend this class to specify prefixes whose possibly-appended strings should be analysed.
*/
abstract class InterestingPrefix extends CompileTimeConstantExpr {
/**
* Gets the offset in this constant string where the interesting prefix begins.
*/
abstract int getOffset();
/**
* Gets an expression that may follow this prefix in a derived string.
*/
Expr getAnAppendedExpression() { mayFollowInterestingPrefix(this, result) }
}
private Expr getAnInterestingPrefix(InterestingPrefix root) {
result = root
or
result.(AddExpr).getAnOperand() = getAnInterestingPrefix(root)
}
private class StringBuilderAppend extends MethodAccess {
StringBuilderAppend() {
this.getMethod().getDeclaringType() instanceof StringBuildingType and
this.getMethod().hasName("append")
}
}
private class StringBuilderConstructorOrAppend extends Call {
StringBuilderConstructorOrAppend() {
this instanceof StringBuilderAppend or
this.(ClassInstanceExpr).getConstructedType() instanceof StringBuildingType
}
}
private Expr getQualifier(Expr e) { result = e.(MethodAccess).getQualifier() }
/**
* An extension of `StringBuilderVar` that also accounts for strings appended in StringBuilder/Buffer's constructor
* and in `append` calls chained onto the constructor call.
*
* The original `StringBuilderVar` doesn't care about these because it is designed to model taint, and
* in taint rules terms these are not needed, as the connection between construction, appends and the
* eventual `toString` is more obvious.
*/
private class StringBuilderVarExt extends StringBuilderVar {
/**
* Returns a first assignment after this StringBuilderVar is first assigned.
*
* For example, for `StringBuilder sbv = new StringBuilder("1").append("2"); sbv.append("3").append("4");`
* this returns the append of `"3"`.
*/
private StringBuilderAppend getAFirstAppendAfterAssignment() {
result = this.getAnAppend() and not result = this.getNextAppend(_)
}
/**
* Gets the next `append` after `prev`, where `prev` is, perhaps after some more `append` or other
* chained calls, assigned to this `StringBuilderVar`.
*/
private StringBuilderAppend getNextAssignmentChainedAppend(StringBuilderConstructorOrAppend prev) {
getQualifier*(result) = this.getAnAssignedValue() and
result.getQualifier() = prev
}
/**
* Get a constructor call or `append` call that contributes a string to this string builder.
*/
StringBuilderConstructorOrAppend getAConstructorOrAppend() {
exists(this.getNextAssignmentChainedAppend(result)) or
result = this.getAnAssignedValue() or
result = this.getAnAppend()
}
/**
* Like `StringBuilderVar.getNextAppend`, except including appends and constructors directly
* assigned to this `StringBuilderVar`.
*/
private StringBuilderAppend getNextAppendIncludingAssignmentChains(
StringBuilderConstructorOrAppend prev
) {
result = this.getNextAssignmentChainedAppend(prev)
or
prev = this.getAnAssignedValue() and
result = this.getAFirstAppendAfterAssignment()
or
result = this.getNextAppend(prev)
}
/**
* Implements `StringBuilderVarExt.getNextAppendIncludingAssignmentChains+(prev)`.
*/
pragma[nomagic]
StringBuilderAppend getSubsequentAppendIncludingAssignmentChains(
StringBuilderConstructorOrAppend prev
) {
result = this.getNextAppendIncludingAssignmentChains(prev) or
result =
this.getSubsequentAppendIncludingAssignmentChains(this.getNextAppendIncludingAssignmentChains(prev))
}
}
/**
* Holds if `follows` may be concatenated after `prefix`.
*/
private predicate mayFollowInterestingPrefix(InterestingPrefix prefix, Expr follows) {
// Expressions that come after an interesting prefix in a tree of string additions:
follows =
any(AddExpr add | add.getLeftOperand() = getAnInterestingPrefix(prefix)).getRightOperand()
or
// Sanitize expressions that come after an interesting prefix in a sequence of StringBuilder operations:
exists(
StringBuilderConstructorOrAppend appendSanitizingConstant, StringBuilderAppend subsequentAppend,
StringBuilderVarExt v
|
appendSanitizingConstant = v.getAConstructorOrAppend() and
appendSanitizingConstant.getArgument(0) = getAnInterestingPrefix(prefix) and
v.getSubsequentAppendIncludingAssignmentChains(appendSanitizingConstant) = subsequentAppend and
follows = subsequentAppend.getArgument(0)
)
or
// Sanitize expressions that come after an interesting prefix in the args to a format call:
exists(
FormattingCall formatCall, FormatString formatString, int prefixOffset, int laterOffset,
int sanitizedArg
|
formatString = unique(FormatString fs | fs = formatCall.getAFormatString()) and
(
// An interesting prefix argument comes before this:
exists(int argIdx |
formatCall.getArgumentToBeFormatted(argIdx) = prefix and
prefixOffset = formatString.getAnArgUsageOffset(argIdx)
)
or
// The format string itself contains an interesting prefix that precedes subsequent arguments:
formatString = prefix.getStringValue() and
prefixOffset = prefix.getOffset()
) and
laterOffset > prefixOffset and
laterOffset = formatString.getAnArgUsageOffset(sanitizedArg) and
follows = formatCall.getArgumentToBeFormatted(sanitizedArg)
)
}

View File

@@ -484,10 +484,10 @@ class BaseSsaVariable extends TBaseSsaVariable {
string toString() { none() }
Location getLocation() { result = getCFGNode().getLocation() }
Location getLocation() { result = this.getCFGNode().getLocation() }
/** Gets the `BasicBlock` in which this SSA variable is defined. */
BasicBlock getBasicBlock() { result = getCFGNode().getBasicBlock() }
BasicBlock getBasicBlock() { result = this.getCFGNode().getBasicBlock() }
/** Gets an access of this SSA variable. */
RValue getAUse() { ssaDefReachesUse(_, this, result) }
@@ -532,14 +532,16 @@ class BaseSsaVariable extends TBaseSsaVariable {
/** An SSA variable that is defined by a `VariableUpdate`. */
class BaseSsaUpdate extends BaseSsaVariable, TSsaUpdate {
BaseSsaUpdate() {
exists(VariableUpdate upd | upd = this.getCFGNode() and getDestVar(upd) = getSourceVariable())
exists(VariableUpdate upd |
upd = this.getCFGNode() and getDestVar(upd) = this.getSourceVariable()
)
}
override string toString() { result = "SSA def(" + getSourceVariable() + ")" }
override string toString() { result = "SSA def(" + this.getSourceVariable() + ")" }
/** Gets the `VariableUpdate` defining the SSA variable. */
VariableUpdate getDefiningExpr() {
result = this.getCFGNode() and getDestVar(result) = getSourceVariable()
result = this.getCFGNode() and getDestVar(result) = this.getSourceVariable()
}
}
@@ -548,30 +550,31 @@ class BaseSsaUpdate extends BaseSsaVariable, TSsaUpdate {
* includes initial values of parameters, fields, and closure variables.
*/
class BaseSsaImplicitInit extends BaseSsaVariable, TSsaEntryDef {
override string toString() { result = "SSA init(" + getSourceVariable() + ")" }
override string toString() { result = "SSA init(" + this.getSourceVariable() + ")" }
/** Holds if this is a closure variable that captures the value of `capturedvar`. */
predicate captures(BaseSsaVariable capturedvar) {
ssaDefReachesCapture(_, capturedvar, getSourceVariable())
ssaDefReachesCapture(_, capturedvar, this.getSourceVariable())
}
/**
* Holds if the SSA variable is a parameter defined by its initial value in the callable.
*/
predicate isParameterDefinition(Parameter p) {
getSourceVariable() = TLocalVar(p.getCallable(), p) and p.getCallable().getBody() = getCFGNode()
this.getSourceVariable() = TLocalVar(p.getCallable(), p) and
p.getCallable().getBody() = this.getCFGNode()
}
}
/** An SSA phi node. */
class BaseSsaPhiNode extends BaseSsaVariable, TSsaPhiNode {
override string toString() { result = "SSA phi(" + getSourceVariable() + ")" }
override string toString() { result = "SSA phi(" + this.getSourceVariable() + ")" }
/** Gets an input to the phi node defining the SSA variable. */
BaseSsaVariable getAPhiInput() {
exists(BasicBlock phiPred, BaseSsaSourceVariable v |
v = getSourceVariable() and
getCFGNode().(BasicBlock).getABBPredecessor() = phiPred and
v = this.getSourceVariable() and
this.getCFGNode().(BasicBlock).getABBPredecessor() = phiPred and
ssaDefReachesEndOfBlock(v, result, phiPred)
)
}

View File

@@ -104,7 +104,9 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
"java.util;Map$Entry;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
"java.lang;Iterable;true;iterator;();;Element of Argument[-1];Element of ReturnValue;value",
"java.lang;Iterable;true;spliterator;();;Element of Argument[-1];Element of ReturnValue;value",
"java.lang;Iterable;true;forEach;(Consumer);;Element of Argument[-1];Parameter[0] of Argument[0];value",
"java.util;Iterator;true;next;;;Element of Argument[-1];ReturnValue;value",
"java.util;Iterator;true;forEachRemaining;(Consumer);;Element of Argument[-1];Parameter[0] of Argument[0];value",
"java.util;ListIterator;true;previous;;;Element of Argument[-1];ReturnValue;value",
"java.util;ListIterator;true;add;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;ListIterator;true;set;(Object);;Argument[0];Element of Argument[-1];value",
@@ -135,6 +137,8 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
"java.util;Map;true;merge;(Object,Object,BiFunction);;Argument[1];MapValue of Argument[-1];value",
"java.util;Map;true;putAll;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
"java.util;Map;true;putAll;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
"java.util;Map;true;forEach;(BiConsumer);;MapKey of Argument[-1];Parameter[0] of Argument[0];value",
"java.util;Map;true;forEach;(BiConsumer);;MapValue of Argument[-1];Parameter[1] of Argument[0];value",
"java.util;Collection;true;parallelStream;();;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Collection;true;stream;();;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Collection;true;toArray;;;Element of Argument[-1];ArrayElement of ReturnValue;value",

View File

@@ -8,9 +8,9 @@ private import semmle.code.java.dispatch.VirtualDispatch as VirtualDispatch
private module DispatchImpl {
/** Gets a viable implementation of the target of the given `Call`. */
DataFlowCallable viableCallable(DataFlowCall c) {
result = VirtualDispatch::viableCallable(c.asCall())
result.asCallable() = VirtualDispatch::viableCallable(c.asCall())
or
result.(SummarizedCallable) = c.asCall().getCallee().getSourceDeclaration()
result.(SummarizedCallable).asCallable() = c.asCall().getCallee().getSourceDeclaration()
}
/**
@@ -93,31 +93,32 @@ private module DispatchImpl {
* qualifier is a parameter of the enclosing callable `c`.
*/
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) {
mayBenefitFromCallContext(call.asCall(), c, _)
mayBenefitFromCallContext(call.asCall(), c.asCallable(), _)
}
/**
* Gets a viable dispatch target of `call` in the context `ctx`. This is
* restricted to those `call`s for which a context might make a difference.
*/
Method viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
result = viableCallable(call) and
exists(int i, Callable c, Method def, RefType t, boolean exact, MethodAccess ma |
ma = call.asCall() and
mayBenefitFromCallContext(ma, c, i) and
c = viableCallable(ctx) and
c = viableCallable(ctx).asCallable() and
contextArgHasType(ctx.asCall(), i, t, exact) and
ma.getMethod().getSourceDeclaration() = def
|
exact = true and result = VirtualDispatch::exactMethodImpl(def, t.getSourceDeclaration())
exact = true and
result.asCallable() = VirtualDispatch::exactMethodImpl(def, t.getSourceDeclaration())
or
exact = false and
exists(RefType t2 |
result = VirtualDispatch::viableMethodImpl(def, t.getSourceDeclaration(), t2) and
result.asCallable() = VirtualDispatch::viableMethodImpl(def, t.getSourceDeclaration(), t2) and
not failsUnification(t, t2)
)
or
result = def and def instanceof SummarizedCallable
result.asCallable() = def and result instanceof SummarizedCallable
)
}

View File

@@ -2,6 +2,42 @@ private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public
import Cached
module DataFlowImplCommonPublic {
private newtype TFlowFeature =
TFeatureHasSourceCallContext() or
TFeatureHasSinkCallContext() or
TFeatureEqualSourceSinkCallContext()
/** A flow configuration feature for use in `Configuration::getAFeature()`. */
class FlowFeature extends TFlowFeature {
string toString() { none() }
}
/**
* A flow configuration feature that implies that sources have some existing
* call context.
*/
class FeatureHasSourceCallContext extends FlowFeature, TFeatureHasSourceCallContext {
override string toString() { result = "FeatureHasSourceCallContext" }
}
/**
* A flow configuration feature that implies that sinks have some existing
* call context.
*/
class FeatureHasSinkCallContext extends FlowFeature, TFeatureHasSinkCallContext {
override string toString() { result = "FeatureHasSinkCallContext" }
}
/**
* A flow configuration feature that implies that source-sink pairs have some
* shared existing call context.
*/
class FeatureEqualSourceSinkCallContext extends FlowFeature, TFeatureEqualSourceSinkCallContext {
override string toString() { result = "FeatureEqualSourceSinkCallContext" }
}
}
/**
* The cost limits for the `AccessPathFront` to `AccessPathApprox` expansion.
*
@@ -251,7 +287,7 @@ private module Cached {
predicate forceCachingInSameStage() { any() }
cached
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = n.getEnclosingCallable() }
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = nodeGetEnclosingCallable(n) }
cached
predicate callEnclosingCallable(DataFlowCall call, DataFlowCallable c) {
@@ -316,9 +352,7 @@ private module Cached {
}
cached
predicate parameterNode(Node n, DataFlowCallable c, int i) {
n.(ParameterNode).isParameterOf(c, i)
}
predicate parameterNode(Node p, DataFlowCallable c, int pos) { isParameterNode(p, c, pos) }
cached
predicate argumentNode(Node n, DataFlowCall call, int pos) {
@@ -801,6 +835,9 @@ private module Cached {
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call))
}
cached
predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) }
cached
newtype TCallContext =
TAnyCallContext() or

View File

@@ -9,6 +9,19 @@ private import tainttracking1.TaintTrackingParameter::Private
private import tainttracking1.TaintTrackingParameter::Public
module Consistency {
private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
/** A class for configuring the consistency queries. */
class ConsistencyConfiguration extends TConsistencyConfiguration {
string toString() { none() }
/** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
predicate postWithInFlowExclude(Node n) { none() }
/** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
}
private class RelevantNode extends Node {
RelevantNode() {
this instanceof ArgumentNode or
@@ -31,7 +44,7 @@ module Consistency {
query predicate uniqueEnclosingCallable(Node n, string msg) {
exists(int c |
n instanceof RelevantNode and
c = count(n.getEnclosingCallable()) and
c = count(nodeGetEnclosingCallable(n)) and
c != 1 and
msg = "Node should have one enclosing callable but has " + c + "."
)
@@ -85,13 +98,13 @@ module Consistency {
}
query predicate parameterCallable(ParameterNode p, string msg) {
exists(DataFlowCallable c | p.isParameterOf(c, _) and c != p.getEnclosingCallable()) and
exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
msg = "Callable mismatch for parameter."
}
query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
simpleLocalFlowStep(n1, n2) and
n1.getEnclosingCallable() != n2.getEnclosingCallable() and
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
msg = "Local flow step does not preserve enclosing callable."
}
@@ -106,7 +119,7 @@ module Consistency {
query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
isUnreachableInCall(n, call) and
exists(DataFlowCallable c |
c = n.getEnclosingCallable() and
c = nodeGetEnclosingCallable(n) and
not viableCallable(call) = c
) and
msg = "Call context for isUnreachableInCall is inconsistent with call graph."
@@ -120,7 +133,7 @@ module Consistency {
n.(ArgumentNode).argumentOf(call, _) and
msg = "ArgumentNode and call does not share enclosing callable."
) and
n.getEnclosingCallable() != call.getEnclosingCallable()
nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
}
// This predicate helps the compiler forget that in some languages
@@ -151,7 +164,7 @@ module Consistency {
}
query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
n.getEnclosingCallable() != n.getPreUpdateNode().getEnclosingCallable() and
nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
msg = "PostUpdateNode does not share callable with its pre-update node."
}
@@ -164,7 +177,7 @@ module Consistency {
query predicate argHasPostUpdate(ArgumentNode n, string msg) {
not hasPost(n) and
not isImmutableOrUnobservable(n) and
not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
msg = "ArgumentNode is missing PostUpdateNode."
}
@@ -175,7 +188,9 @@ module Consistency {
query predicate postWithInFlow(Node n, string msg) {
isPostUpdateNode(n) and
not clearsContent(n, _) and
simpleLocalFlowStep(_, n) and
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
msg = "PostUpdateNode should not be the target of local flow."
}
}

View File

@@ -14,14 +14,14 @@ newtype TNode =
not e.getParent*() instanceof Annotation
} or
TExplicitParameterNode(Parameter p) {
exists(p.getCallable().getBody()) or p.getCallable() instanceof SummarizedCallable
exists(p.getCallable().getBody()) or p.getCallable() = any(SummarizedCallable sc).asCallable()
} or
TImplicitVarargsArray(Call c) {
c.getCallee().isVarargs() and
not exists(Argument arg | arg.getCall() = c and arg.isExplicitVarargsArray())
} or
TInstanceParameterNode(Callable c) {
(exists(c.getBody()) or c instanceof SummarizedCallable) and
(exists(c.getBody()) or c = any(SummarizedCallable sc).asCallable()) and
not c.isStatic()
} or
TImplicitInstanceAccess(InstanceAccessExt ia) { not ia.isExplicit(_) } or
@@ -44,7 +44,8 @@ newtype TNode =
} or
TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
FlowSummaryImpl::Private::summaryNodeRange(c, state)
}
} or
TFieldValueNode(Field f)
private predicate explicitInstanceArgument(Call call, Expr instarg) {
call instanceof MethodAccess and
@@ -94,19 +95,12 @@ module Public {
result = this.(MallocNode).getClassInstanceExpr().getType()
or
result = this.(ImplicitPostUpdateNode).getPreUpdateNode().getType()
or
result = this.(FieldValueNode).getField().getType()
}
/** Gets the callable in which this node occurs. */
Callable getEnclosingCallable() {
result = this.asExpr().getEnclosingCallable() or
result = this.asParameter().getCallable() or
result = this.(ImplicitVarargsArray).getCall().getEnclosingCallable() or
result = this.(InstanceParameterNode).getCallable() or
result = this.(ImplicitInstanceAccess).getInstanceAccess().getEnclosingCallable() or
result = this.(MallocNode).getClassInstanceExpr().getEnclosingCallable() or
result = this.(ImplicitPostUpdateNode).getPreUpdateNode().getEnclosingCallable() or
this = TSummaryInternalNode(result, _)
}
Callable getEnclosingCallable() { result = nodeGetEnclosingCallable(this).asCallable() }
private Type getImprovedTypeBound() {
exprTypeFlow(this.asExpr(), result, _) or
@@ -117,9 +111,9 @@ module Public {
* Gets an upper bound on the type of this node.
*/
Type getTypeBound() {
result = getImprovedTypeBound()
result = this.getImprovedTypeBound()
or
result = getType() and not exists(getImprovedTypeBound())
result = this.getType() and not exists(this.getImprovedTypeBound())
}
/**
@@ -132,7 +126,7 @@ module Public {
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
@@ -257,6 +251,18 @@ module Public {
abstract Node getPreUpdateNode();
}
/**
* A node representing the value of a field.
*/
class FieldValueNode extends Node, TFieldValueNode {
/** Gets the field corresponding to this node. */
Field getField() { this = TFieldValueNode(result) }
override string toString() { result = getField().toString() }
override Location getLocation() { result = getField().getLocation() }
}
/**
* Gets the node that occurs as the qualifier of `fa`.
*/
@@ -288,9 +294,9 @@ private class NewExpr extends PostUpdateNode, TExprNode {
* A `PostUpdateNode` that is not a `ClassInstanceExpr`.
*/
abstract private class ImplicitPostUpdateNode extends PostUpdateNode {
override Location getLocation() { result = getPreUpdateNode().getLocation() }
override Location getLocation() { result = this.getPreUpdateNode().getLocation() }
override string toString() { result = getPreUpdateNode().toString() + " [post update]" }
override string toString() { result = this.getPreUpdateNode().toString() + " [post update]" }
}
private class ExplicitExprPostUpdate extends ImplicitPostUpdateNode, TExplicitExprPostUpdate {
@@ -304,6 +310,24 @@ private class ImplicitExprPostUpdate extends ImplicitPostUpdateNode, TImplicitEx
}
module Private {
/** Gets the callable in which this node occurs. */
DataFlowCallable nodeGetEnclosingCallable(Node n) {
result.asCallable() = n.asExpr().getEnclosingCallable() or
result.asCallable() = n.asParameter().getCallable() or
result.asCallable() = n.(ImplicitVarargsArray).getCall().getEnclosingCallable() or
result.asCallable() = n.(InstanceParameterNode).getCallable() or
result.asCallable() = n.(ImplicitInstanceAccess).getInstanceAccess().getEnclosingCallable() or
result.asCallable() = n.(MallocNode).getClassInstanceExpr().getEnclosingCallable() or
result = nodeGetEnclosingCallable(n.(ImplicitPostUpdateNode).getPreUpdateNode()) or
n = TSummaryInternalNode(result, _) or
result.asFieldScope() = n.(FieldValueNode).getField()
}
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos) {
p.isParameterOf(c.asCallable(), pos)
}
/**
* A data flow node that occurs as the argument of a call and is passed as-is
* to the callable. Arguments that are wrapped in an implicit varargs array

View File

@@ -5,8 +5,10 @@ private import DataFlowDispatch
private import semmle.code.java.controlflow.Guards
private import semmle.code.java.dataflow.SSA
private import ContainerFlow
private import semmle.code.java.dataflow.FlowSteps
private import semmle.code.java.dataflow.FlowSummary
private import FlowSummaryImpl as FlowSummaryImpl
private import DataFlowImplConsistency
import DataFlowNodes::Private
private newtype TReturnKind = TNormalReturnKind()
@@ -32,12 +34,18 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
/**
* Holds if data can flow from `node1` to `node2` through a static field.
*/
private predicate staticFieldStep(ExprNode node1, ExprNode node2) {
private predicate staticFieldStep(Node node1, Node node2) {
exists(Field f |
f.isStatic() and
f.getAnAssignedValue() = node1.asExpr() and
node2.(FieldValueNode).getField() = f
)
or
exists(Field f, FieldRead fr |
f.isStatic() and
f.getAnAssignedValue() = node1.getExpr() and
node1.(FieldValueNode).getField() = f and
fr.getField() = f and
fr = node2.getExpr() and
fr = node2.asExpr() and
hasNonlocalValue(fr)
)
}
@@ -67,9 +75,14 @@ private predicate variableCaptureStep(Node node1, ExprNode node2) {
* variable capture.
*/
predicate jumpStep(Node node1, Node node2) {
staticFieldStep(node1, node2) or
variableCaptureStep(node1, node2) or
staticFieldStep(node1, node2)
or
variableCaptureStep(node1, node2)
or
variableCaptureStep(node1.(PostUpdateNode).getPreUpdateNode(), node2)
or
any(AdditionalValueStep a).step(node1, node2) and
node1.getEnclosingCallable() != node2.getEnclosingCallable()
}
/**
@@ -138,11 +151,10 @@ predicate readStep(Node node1, Content f, Node node2) {
* in `x.f = newValue`.
*/
predicate clearsContent(Node n, Content c) {
c instanceof FieldContent and
(
n = any(PostUpdateNode pun | storeStep(_, c, pun)).getPreUpdateNode()
or
FlowSummaryImpl::Private::Steps::summaryStoresIntoArg(c, n)
exists(FieldAccess fa |
instanceFieldAssign(_, fa) and
n = getFieldQualifier(fa) and
c.(FieldContent).getField() = fa.getField()
)
or
FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c)
@@ -209,7 +221,30 @@ class CastNode extends ExprNode {
CastNode() { this.getExpr() instanceof CastExpr }
}
class DataFlowCallable = Callable;
private newtype TDataFlowCallable =
TCallable(Callable c) or
TFieldScope(Field f)
class DataFlowCallable extends TDataFlowCallable {
Callable asCallable() { this = TCallable(result) }
Field asFieldScope() { this = TFieldScope(result) }
RefType getDeclaringType() {
result = asCallable().getDeclaringType() or
result = asFieldScope().getDeclaringType()
}
string toString() {
result = asCallable().toString() or
result = "Field scope: " + asFieldScope().toString()
}
Location getLocation() {
result = asCallable().getLocation() or
result = asFieldScope().getLocation()
}
}
class DataFlowExpr = Expr;
@@ -255,7 +290,9 @@ class SrcCall extends DataFlowCall, TCall {
SrcCall() { this = TCall(call) }
override DataFlowCallable getEnclosingCallable() { result = call.getEnclosingCallable() }
override DataFlowCallable getEnclosingCallable() {
result.asCallable() = call.getEnclosingCallable()
}
override string toString() { result = call.toString() }
@@ -329,19 +366,12 @@ predicate forceHighPrecision(Content c) {
c instanceof ArrayContent or c instanceof CollectionContent
}
/**
* Holds if `n` does not require a `PostUpdateNode` as it either cannot be
* modified or its modification cannot be observed, for example if it is a
* freshly created object that is not saved in a variable.
*
* This predicate is only used for consistency checks.
*/
predicate isImmutableOrUnobservable(Node n) {
n.getType() instanceof ImmutableType or n instanceof ImplicitVarargsArray
}
/** Holds if `n` should be hidden from path explanations. */
predicate nodeIsHidden(Node n) { n instanceof SummaryNode }
predicate nodeIsHidden(Node n) {
n instanceof SummaryNode
or
n.(ParameterNode).isParameterOf(any(SummarizedCallable c).asCallable(), _)
}
class LambdaCallKind = Method; // the "apply" method in the functional interface
@@ -349,10 +379,10 @@ class LambdaCallKind = Method; // the "apply" method in the functional interface
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) {
exists(ClassInstanceExpr func, Interface t, FunctionalInterface interface |
creation.asExpr() = func and
func.getAnonymousClass().getAMethod() = c and
func.getAnonymousClass().getAMethod() = c.asCallable() and
func.getConstructedType().extendsOrImplements+(t) and
t.getSourceDeclaration() = interface and
c.(Method).overridesOrInstantiates+(pragma[only_bind_into](kind)) and
c.asCallable().(Method).overridesOrInstantiates+(pragma[only_bind_into](kind)) and
pragma[only_bind_into](kind) = interface.getRunMethod().getSourceDeclaration()
)
}
@@ -369,3 +399,20 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
/** Extra data-flow steps needed for lambda flow analysis. */
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
/**
* Holds if flow is allowed to pass from parameter `p` and back to itself as a
* side-effect, resulting in a summary from `p` to itself.
*
* One example would be to allow flow like `p.foo = p.bar;`, which is disallowed
* by default as a heuristic.
*/
predicate allowParameterReturnInSelf(ParameterNode p) {
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p)
}
private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration {
override predicate argHasPostUpdateExclude(ArgumentNode n) {
n.getType() instanceof ImmutableType or n instanceof ImplicitVarargsArray
}
}

View File

@@ -101,6 +101,8 @@ predicate hasNonlocalValue(FieldRead fr) {
predicate localFlowStep(Node node1, Node node2) {
simpleLocalFlowStep(node1, node2)
or
adjacentUseUse(node1.asExpr(), node2.asExpr())
or
// Simple flow through library code is included in the exposed local
// step relation, even though flow is technically inter-procedural
FlowSummaryImpl::Private::Steps::summaryThroughStep(node1, node2, true)
@@ -131,7 +133,8 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
adjacentUseUse(node1.asExpr(), node2.asExpr()) and
not exists(FieldRead fr |
hasNonlocalValue(fr) and fr.getField().isStatic() and fr = node1.asExpr()
)
) and
not FlowSummaryImpl::Private::Steps::summaryClearsContentArg(node1, _)
or
ThisFlow::adjacentThisRefs(node1, node2)
or
@@ -155,6 +158,10 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
)
or
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true)
or
any(AdditionalValueStep a).step(node1, node2) and
pragma[only_bind_out](node1.getEnclosingCallable()) =
pragma[only_bind_out](node2.getEnclosingCallable())
}
private newtype TContent =

View File

@@ -85,6 +85,9 @@ module Public {
/** Holds if this stack contains summary component `c`. */
predicate contains(SummaryComponent c) { c = this.drop(_).head() }
/** Gets the bottom element of this stack. */
SummaryComponent bottom() { result = this.drop(this.length() - 1).head() }
/** Gets a textual representation of this stack. */
string toString() {
exists(SummaryComponent head, SummaryComponentStack tail |
@@ -124,6 +127,38 @@ module Public {
SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) }
}
private predicate noComponentSpecificCsv(SummaryComponent sc) {
not exists(getComponentSpecificCsv(sc))
}
/** Gets a textual representation of this component used for flow summaries. */
private string getComponentCsv(SummaryComponent sc) {
result = getComponentSpecificCsv(sc)
or
noComponentSpecificCsv(sc) and
(
exists(int i | sc = TParameterSummaryComponent(i) and result = "Parameter[" + i + "]")
or
exists(int i | sc = TArgumentSummaryComponent(i) and result = "Argument[" + i + "]")
or
sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue"
)
}
/** Gets a textual representation of this stack used for flow summaries. */
string getComponentStackCsv(SummaryComponentStack stack) {
exists(SummaryComponent head, SummaryComponentStack tail |
head = stack.head() and
tail = stack.tail() and
result = getComponentCsv(head) + " of " + getComponentStackCsv(tail)
)
or
exists(SummaryComponent c |
stack = TSingletonSummaryComponentStack(c) and
result = getComponentCsv(c)
)
}
/**
* A class that exists for QL technical reasons only (the IPA type used
* to represent component stacks needs to be bounded).
@@ -197,6 +232,8 @@ module Private {
or
tail.(RequiredSummaryComponentStack).required(TParameterSummaryComponent(_)) and
head = thisParam()
or
derivedFluentFlowPush(_, _, _, head, tail, _)
}
pragma[nomagic]
@@ -210,7 +247,7 @@ module Private {
c.propagatesFlow(output, input, preservesValue) and
preservesValue = true and
isCallbackParameter(input) and
isContentOfArgument(output)
isContentOfArgument(output, _)
or
// flow from the receiver of a callback into the instance-parameter
exists(SummaryComponentStack s, SummaryComponentStack callbackRef |
@@ -222,16 +259,81 @@ module Private {
output = TConsSummaryComponentStack(thisParam(), input) and
preservesValue = true
)
or
exists(SummaryComponentStack arg, SummaryComponentStack return |
derivedFluentFlow(c, input, arg, return, preservesValue)
|
arg.length() = 1 and
output = return
or
exists(SummaryComponent head, SummaryComponentStack tail |
derivedFluentFlowPush(c, input, arg, head, tail, 0) and
output = SummaryComponentStack::push(head, tail)
)
)
or
// Chain together summaries where values get passed into callbacks along the way
exists(SummaryComponentStack mid, boolean preservesValue1, boolean preservesValue2 |
c.propagatesFlow(input, mid, preservesValue1) and
c.propagatesFlow(mid, output, preservesValue2) and
mid.drop(mid.length() - 2) =
SummaryComponentStack::push(TParameterSummaryComponent(_),
SummaryComponentStack::singleton(TArgumentSummaryComponent(_))) and
preservesValue = preservesValue1.booleanAnd(preservesValue2)
)
}
/**
* Holds if `c` has a flow summary from `input` to `arg`, where `arg`
* writes to (contents of) the `i`th argument, and `c` has a
* value-preserving flow summary from the `i`th argument to a return value
* (`return`).
*
* In such a case, we derive flow from `input` to (contents of) the return
* value.
*
* As an example, this simplifies modeling of fluent methods:
* for `StringBuilder.append(x)` with a specified value flow from qualifier to
* return value and taint flow from argument 0 to the qualifier, then this
* allows us to infer taint flow from argument 0 to the return value.
*/
pragma[nomagic]
private predicate derivedFluentFlow(
SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack arg,
SummaryComponentStack return, boolean preservesValue
) {
exists(int i |
summary(c, input, arg, preservesValue) and
isContentOfArgument(arg, i) and
summary(c, SummaryComponentStack::singleton(TArgumentSummaryComponent(i)), return, true) and
return.bottom() = TReturnSummaryComponent(_)
)
}
pragma[nomagic]
private predicate derivedFluentFlowPush(
SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack arg,
SummaryComponent head, SummaryComponentStack tail, int i
) {
derivedFluentFlow(c, input, arg, tail, _) and
head = arg.drop(i).head() and
i = arg.length() - 2
or
exists(SummaryComponent head0, SummaryComponentStack tail0 |
derivedFluentFlowPush(c, input, arg, head0, tail0, i + 1) and
head = arg.drop(i).head() and
tail = SummaryComponentStack::push(head0, tail0)
)
}
private predicate isCallbackParameter(SummaryComponentStack s) {
s.head() = TParameterSummaryComponent(_) and exists(s.tail())
}
private predicate isContentOfArgument(SummaryComponentStack s) {
s.head() = TContentSummaryComponent(_) and isContentOfArgument(s.tail())
private predicate isContentOfArgument(SummaryComponentStack s, int i) {
s.head() = TContentSummaryComponent(_) and isContentOfArgument(s.tail(), i)
or
s = TSingletonSummaryComponentStack(TArgumentSummaryComponent(_))
s = TSingletonSummaryComponentStack(TArgumentSummaryComponent(i))
}
private predicate outputState(SummarizedCallable c, SummaryComponentStack s) {
@@ -261,7 +363,10 @@ module Private {
private newtype TSummaryNodeState =
TSummaryNodeInputState(SummaryComponentStack s) { inputState(_, s) } or
TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) }
TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } or
TSummaryNodeClearsContentState(int i, boolean post) {
any(SummarizedCallable sc).clearsContent(i, _) and post in [false, true]
}
/**
* A state used to break up (complex) flow summaries into atomic flow steps.
@@ -308,6 +413,12 @@ module Private {
this = TSummaryNodeOutputState(s) and
result = "to write: " + s
)
or
exists(int i, boolean post, string postStr |
this = TSummaryNodeClearsContentState(i, post) and
(if post = true then postStr = " (post)" else postStr = "") and
result = "clear: " + i + postStr
)
}
}
@@ -329,6 +440,11 @@ module Private {
not parameterReadState(c, state, _)
or
state.isOutputState(c, _)
or
exists(int i |
c.clearsContent(i, _) and
state = TSummaryNodeClearsContentState(i, _)
)
}
pragma[noinline]
@@ -364,6 +480,8 @@ module Private {
parameterReadState(c, _, i)
or
isParameterPostUpdate(_, c, i)
or
c.clearsContent(i, _)
}
private predicate callbackOutput(
@@ -436,6 +554,12 @@ module Private {
)
)
)
or
exists(SummarizedCallable c, int i, ParamNode p |
n = summaryNode(c, TSummaryNodeClearsContentState(i, false)) and
p.isParameterOf(c, i) and
result = getNodeType(p)
)
}
/** Holds if summary node `out` contains output of kind `rk` from call `c`. */
@@ -461,6 +585,9 @@ module Private {
exists(SummarizedCallable c, int i |
isParameterPostUpdate(post, c, i) and
pre.(ParamNode).isParameterOf(c, i)
or
pre = summaryNode(c, TSummaryNodeClearsContentState(i, false)) and
post = summaryNode(c, TSummaryNodeClearsContentState(i, true))
)
or
exists(SummarizedCallable callable, SummaryComponentStack s |
@@ -478,6 +605,22 @@ module Private {
)
}
/**
* Holds if flow is allowed to pass from parameter `p`, to a return
* node, and back out to `p`.
*/
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
exists(SummarizedCallable c, int i | p.isParameterOf(c, i) |
c.clearsContent(i, _)
or
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
summary(c, inputContents, outputContents, _) and
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(i)) and
outputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(i))
)
)
}
/** Provides a compilation of flow summaries to atomic data-flow steps. */
module Steps {
/**
@@ -498,17 +641,11 @@ module Private {
preservesValue = false and not summary(c, inputContents, outputContents, true)
)
or
// If flow through a method updates a parameter from some input A, and that
// parameter also is returned through B, then we'd like a combined flow from A
// to B as well. As an example, this simplifies modeling of fluent methods:
// for `StringBuilder.append(x)` with a specified value flow from qualifier to
// return value and taint flow from argument 0 to the qualifier, then this
// allows us to infer taint flow from argument 0 to the return value.
succ instanceof ParamNode and summaryPostUpdateNode(pred, succ) and preservesValue = true
or
// Similarly we would like to chain together summaries where values get passed
// into callbacks along the way.
pred instanceof ArgNode and summaryPostUpdateNode(succ, pred) and preservesValue = true
exists(SummarizedCallable c, int i |
pred.(ParamNode).isParameterOf(c, i) and
succ = summaryNode(c, TSummaryNodeClearsContentState(i, _)) and
preservesValue = true
)
}
/**
@@ -536,10 +673,39 @@ module Private {
}
/**
* Holds if values stored inside content `c` are cleared when passed as
* input of type `input` in `call`.
* Holds if values stored inside content `c` are cleared at `n`. `n` is a
* synthesized summary node, so in order for values to be cleared at calls
* to the relevant method, it is important that flow does not pass over
* the argument, either via use-use flow or def-use flow.
*
* Example:
*
* ```
* a.b = taint;
* a.clearB(); // assume we have a flow summary for `clearB` that clears `b` on the qualifier
* sink(a.b);
* ```
*
* In the above, flow should not pass from `a` on the first line (or the second
* line) to `a` on the third line. Instead, there will be synthesized flow from
* `a` on line 2 to the post-update node for `a` on that line (via an intermediate
* node where field `b` is cleared).
*/
predicate summaryClearsContent(ArgNode arg, Content c) {
predicate summaryClearsContent(Node n, Content c) {
exists(SummarizedCallable sc, int i |
n = summaryNode(sc, TSummaryNodeClearsContentState(i, true)) and
sc.clearsContent(i, c)
)
}
/**
* Holds if values stored inside content `c` are cleared inside a
* callable to which `arg` is an argument.
*
* In such cases, it is important to prevent use-use flow out of
* `arg` (see comment for `summaryClearsContent`).
*/
predicate summaryClearsContentArg(ArgNode arg, Content c) {
exists(DataFlowCall call, int i |
viableCallable(call).(SummarizedCallable).clearsContent(i, c) and
arg.argumentOf(call, i)
@@ -599,25 +765,6 @@ module Private {
ret.getKind() = rk
)
}
/**
* Holds if data is written into content `c` of argument `arg` using a flow summary.
*
* Depending on the type of `c`, this predicate may be relevant to include in the
* definition of `clearsContent()`.
*/
predicate summaryStoresIntoArg(Content c, Node arg) {
exists(ParamUpdateReturnKind rk, ReturnNodeExt ret, PostUpdateNode out |
exists(DataFlowCall call, SummarizedCallable callable |
getNodeEnclosingCallable(ret) = callable and
viableCallable(call) = callable and
summaryStoreStep(_, c, ret) and
ret.getKind() = pragma[only_bind_into](rk) and
out = rk.getAnOutNode(call) and
arg = out.getPreUpdateNode()
)
)
}
}
/**
@@ -855,18 +1002,38 @@ module Private {
module TestOutput {
/** A flow summary to include in the `summary/3` query predicate. */
abstract class RelevantSummarizedCallable extends SummarizedCallable {
/** Gets the string representation of this callable used by `summary/3`. */
string getFullString() { result = this.toString() }
/** Gets the string representation of this callable used by `summary/1`. */
abstract string getCallableCsv();
/** Holds if flow is propagated between `input` and `output`. */
predicate relevantSummary(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) {
this.propagatesFlow(input, output, preservesValue)
}
}
/** A query predicate for outputting flow summaries in QL tests. */
query predicate summary(string callable, string flow, boolean preservesValue) {
/** Render the kind in the format used in flow summaries. */
private string renderKind(boolean preservesValue) {
preservesValue = true and result = "value"
or
preservesValue = false and result = "taint"
}
/**
* A query predicate for outputting flow summaries in semi-colon separated format in QL tests.
* The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind",
* ext is hardcoded to empty.
*/
query predicate summary(string csv) {
exists(
RelevantSummarizedCallable c, SummaryComponentStack input, SummaryComponentStack output
RelevantSummarizedCallable c, SummaryComponentStack input, SummaryComponentStack output,
boolean preservesValue
|
callable = c.getFullString() and
c.propagatesFlow(input, output, preservesValue) and
flow = input + " -> " + output
c.relevantSummary(input, output, preservesValue) and
csv =
c.getCallableCsv() + ";;" + getComponentStackCsv(input) + ";" +
getComponentStackCsv(output) + ";" + renderKind(preservesValue)
)
}
}

View File

@@ -30,7 +30,7 @@ DataFlowType getContentType(Content c) { result = c.getType() }
/** Gets the return type of kind `rk` for callable `c`. */
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) {
result = getErasedRepr(c.getReturnType()) and
result = getErasedRepr(c.asCallable().getReturnType()) and
exists(rk)
}
@@ -62,7 +62,7 @@ predicate summaryElement(DataFlowCallable c, string input, string output, string
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind) and
c = interpretElement(namespace, type, subtypes, name, signature, ext)
c.asCallable() = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
@@ -72,6 +72,32 @@ SummaryComponent interpretComponentSpecific(string c) {
exists(Content content | parseContent(c, content) and result = SummaryComponent::content(content))
}
/** Gets the summary component for specification component `c`, if any. */
private string getContentSpecificCsv(Content c) {
exists(Field f, string package, string className, string fieldName |
f = c.(FieldContent).getField() and
f.hasQualifiedName(package, className, fieldName) and
result = "Field[" + package + "." + className + "." + fieldName + "]"
)
or
exists(SyntheticField f |
f = c.(SyntheticFieldContent).getField() and result = "SyntheticField[" + f + "]"
)
or
c instanceof ArrayContent and result = "ArrayElement"
or
c instanceof CollectionContent and result = "Element"
or
c instanceof MapKeyContent and result = "MapKey"
or
c instanceof MapValueContent and result = "MapValue"
}
/** Gets the textual representation of the content in the format used for flow summaries. */
string getComponentSpecificCsv(SummaryComponent sc) {
exists(Content c | sc = TContentSummaryComponent(c) and result = getContentSpecificCsv(c))
}
class SourceOrSinkElement = Top;
/**
@@ -119,7 +145,7 @@ class InterpretNode extends TInterpretNode {
DataFlowCall asCall() { result.asCall() = this.asElement() }
/** Gets the callable that this node corresponds to, if any. */
DataFlowCallable asCallable() { result = this.asElement() }
DataFlowCallable asCallable() { result.asCallable() = this.asElement() }
/** Gets the target of this call, if any. */
Callable getCallTarget() { result = this.asCall().asCall().getCallee().getSourceDeclaration() }

View File

@@ -285,11 +285,11 @@ private predicate taintPreservingQualifierToMethod(Method m) {
private class StringReplaceMethod extends TaintPreservingCallable {
StringReplaceMethod() {
getDeclaringType() instanceof TypeString and
this.getDeclaringType() instanceof TypeString and
(
hasName("replace") or
hasName("replaceAll") or
hasName("replaceFirst")
this.hasName("replace") or
this.hasName("replaceAll") or
this.hasName("replaceFirst")
)
}
@@ -300,8 +300,8 @@ private predicate unsafeEscape(MethodAccess ma) {
// Removing `<script>` tags using a string-replace method is
// unsafe if such a tag is embedded inside another one (e.g. `<scr<script>ipt>`).
exists(StringReplaceMethod m | ma.getMethod() = m |
ma.getArgument(0).(StringLiteral).getRepresentedString() = "(<script>)" and
ma.getArgument(1).(StringLiteral).getRepresentedString() = ""
ma.getArgument(0).(StringLiteral).getValue() = "(<script>)" and
ma.getArgument(1).(StringLiteral).getValue() = ""
)
}
@@ -376,13 +376,6 @@ private predicate argToQualifierStep(Expr tracked, Expr sink) {
* `arg` is the index of the argument.
*/
private predicate taintPreservingArgumentToQualifier(Method method, int arg) {
exists(Method write |
method.overrides*(write) and
write.hasName("write") and
arg = 0 and
write.getDeclaringType().hasQualifiedName("java.io", "OutputStream")
)
or
method.(TaintPreservingCallable).transfersTaint(arg, -1)
}
@@ -443,7 +436,7 @@ class ObjectOutputStreamVar extends LocalVariableDecl {
}
MethodAccess getAWriteObjectMethodAccess() {
result.getQualifier() = getAnAccess() and
result.getQualifier() = this.getAnAccess() and
result.getMethod().hasName("writeObject")
}
}
@@ -488,7 +481,7 @@ private class FormatterVar extends LocalVariableDecl {
}
MethodAccess getAFormatMethodAccess() {
result.getQualifier() = getAnAccess() and
result.getQualifier() = this.getAnAccess() and
result.getMethod().hasName("format")
}
}
@@ -513,13 +506,13 @@ private class FormatterCallable extends TaintPreservingCallable {
}
override predicate returnsTaintFrom(int arg) {
if this instanceof Constructor then arg = 0 else arg = [-1 .. getNumberOfParameters()]
if this instanceof Constructor then arg = 0 else arg = [-1 .. this.getNumberOfParameters()]
}
override predicate transfersTaint(int src, int sink) {
this.hasName("format") and
sink = -1 and
src = [0 .. getNumberOfParameters()]
src = [0 .. this.getNumberOfParameters()]
}
}
@@ -532,13 +525,13 @@ module StringBuilderVarModule {
* build up a query using string concatenation.
*/
class StringBuilderVar extends LocalVariableDecl {
StringBuilderVar() { getType() instanceof StringBuildingType }
StringBuilderVar() { this.getType() instanceof StringBuildingType }
/**
* Gets a call that adds something to this string builder, from the argument at the given index.
*/
MethodAccess getAnInput(int arg) {
result.getQualifier() = getAChainedReference() and
result.getQualifier() = this.getAChainedReference() and
(
result.getMethod().getName() = "append" and arg = 0
or
@@ -552,20 +545,20 @@ module StringBuilderVarModule {
* Gets a call that appends something to this string builder.
*/
MethodAccess getAnAppend() {
result.getQualifier() = getAChainedReference() and
result.getQualifier() = this.getAChainedReference() and
result.getMethod().getName() = "append"
}
MethodAccess getNextAppend(MethodAccess append) {
result = getAnAppend() and
append = getAnAppend() and
result = this.getAnAppend() and
append = this.getAnAppend() and
(
result.getQualifier() = append
or
not exists(MethodAccess chainAccess | chainAccess.getQualifier() = append) and
exists(RValue sbva1, RValue sbva2 |
adjacentUseUse(sbva1, sbva2) and
append.getQualifier() = getAChainedReference(sbva1) and
append.getQualifier() = this.getAChainedReference(sbva1) and
result.getQualifier() = sbva2
)
)
@@ -575,7 +568,7 @@ module StringBuilderVarModule {
* Gets a call that converts this string builder to a string.
*/
MethodAccess getToStringCall() {
result.getQualifier() = getAChainedReference() and
result.getQualifier() = this.getAChainedReference() and
result.getMethod().getName() = "toString"
}
@@ -590,7 +583,7 @@ module StringBuilderVarModule {
/**
* Gets an expression that refers to this `StringBuilder`, possibly after some chained calls.
*/
Expr getAChainedReference() { result = getAChainedReference(_) }
Expr getAChainedReference() { result = this.getAChainedReference(_) }
}
}

View File

@@ -18,12 +18,12 @@ predicate isLive(Callable c) {
* would imply the liveness of `c`.
*/
Callable possibleLivenessCause(Callable c, string reason) {
c.(Method).overridesOrInstantiates(result.(Method)) and
c.(Method).overridesOrInstantiates(result) and
reason = "is overridden or instantiated by"
or
result.calls(c) and reason = "calls"
or
result.callsConstructor(c.(Constructor)) and reason = "calls constructor"
result.callsConstructor(c) and reason = "calls constructor"
or
exists(ClassInstanceExpr e | e.getEnclosingCallable() = result |
e.getConstructor() = c and reason = "constructs"
@@ -82,19 +82,19 @@ class SuppressedConstructor extends Constructor {
SuppressedConstructor() {
// Must be private or protected to suppress it.
(
isPrivate()
this.isPrivate()
or
// A protected, suppressed constructor only makes sense in a non-abstract class.
isProtected() and not getDeclaringType().isAbstract()
this.isProtected() and not this.getDeclaringType().isAbstract()
) and
// Must be no-arg in order to replace the compiler generated default constructor.
getNumberOfParameters() = 0 and
this.getNumberOfParameters() = 0 and
// Not the compiler-generated constructor itself.
not isDefaultConstructor() and
not this.isDefaultConstructor() and
// Verify that there is only one statement, which is the `super()` call. This exists
// even for empty constructors.
getBody().(BlockStmt).getNumStmt() = 1 and
getBody().(BlockStmt).getAStmt().(SuperConstructorInvocationStmt).getNumArgument() = 0 and
this.getBody().getNumStmt() = 1 and
this.getBody().getAStmt().(SuperConstructorInvocationStmt).getNumArgument() = 0 and
// A constructor that is called is not acting to suppress the default constructor. We permit
// calls from suppressed and default constructors - in both cases, they can only come from
// sub-class constructors.
@@ -105,7 +105,9 @@ class SuppressedConstructor extends Constructor {
) and
// If other constructors are declared, then no compiler-generated constructor is added, so
// this constructor is not acting to suppress the default compiler-generated constructor.
not exists(Constructor other | other = getDeclaringType().getAConstructor() and other != this)
not exists(Constructor other |
other = this.getDeclaringType().getAConstructor() and other != this
)
}
}
@@ -114,7 +116,7 @@ class SuppressedConstructor extends Constructor {
*/
class NamespaceClass extends RefType {
NamespaceClass() {
fromSource() and
this.fromSource() and
// All members, apart from the default constructor and, if present, a "suppressed" constructor
// must be static. There must be at least one member apart from the permitted constructors.
forex(Member m |
@@ -125,7 +127,9 @@ class NamespaceClass extends RefType {
m.isStatic()
) and
// Must only extend other namespace classes, or `Object`.
forall(RefType r | r = getASupertype() | r instanceof TypeObject or r instanceof NamespaceClass)
forall(RefType r | r = this.getASupertype() |
r instanceof TypeObject or r instanceof NamespaceClass
)
}
}
@@ -197,7 +201,7 @@ class DeadClass extends SourceClassOrInterface {
/**
* Identify all the "dead" roots of this dead class.
*/
DeadRoot getADeadRoot() { result = getADeadRoot(getACallable()) }
DeadRoot getADeadRoot() { result = getADeadRoot(this.getACallable()) }
/**
* Holds if this dead class is only used within the class itself.
@@ -206,8 +210,8 @@ class DeadClass extends SourceClassOrInterface {
// Accessed externally if any callable in the class has a possible liveness cause outside the
// class. Only one step is required.
not exists(Callable c |
c = possibleLivenessCause(getACallable()) and
not c = getACallable()
c = possibleLivenessCause(this.getACallable()) and
not c = this.getACallable()
)
}
}
@@ -229,7 +233,7 @@ abstract class WhitelistedLiveClass extends RefType { }
*/
class DeadMethod extends Callable {
DeadMethod() {
fromSource() and
this.fromSource() and
not isLive(this) and
not this.(Constructor).isDefaultConstructor() and
// Ignore `SuppressedConstructor`s in `NamespaceClass`es. There is no reason to use a suppressed
@@ -239,7 +243,7 @@ class DeadMethod extends Callable {
) and
not (
this.(Method).isAbstract() and
exists(Method m | m.overridesOrInstantiates+(this.(Method)) | isLive(m))
exists(Method m | m.overridesOrInstantiates+(this) | isLive(m))
) and
// A getter or setter associated with a live JPA field.
//

View File

@@ -10,7 +10,7 @@ import semmle.code.java.frameworks.jackson.JacksonSerializability
* This defines the set of fields for which we will determine liveness.
*/
library class SourceField extends Field {
SourceField() { fromSource() }
SourceField() { this.fromSource() }
}
/**
@@ -26,7 +26,7 @@ class DeadField extends SourceField {
*/
predicate isInDeadScope() {
// `EnumConstant`s, and fields in dead classes, are reported in other queries.
getDeclaringType() instanceof DeadClass or
this.getDeclaringType() instanceof DeadClass or
this instanceof EnumConstant
}
}
@@ -37,7 +37,7 @@ class DeadField extends SourceField {
*/
class LiveField extends SourceField {
LiveField() {
exists(FieldRead access | access = getAnAccess() |
exists(FieldRead access | access = this.getAnAccess() |
isLive(access.getEnclosingCallable())
or
exists(Annotation a |
@@ -89,11 +89,11 @@ abstract class WhitelistedLiveField extends Field { }
*/
class SerialVersionUIDField extends ReflectivelyReadField {
SerialVersionUIDField() {
hasName("serialVersionUID") and
isStatic() and
isFinal() and
getType().hasName("long") and
getDeclaringType().getASupertype*() instanceof TypeSerializable
this.hasName("serialVersionUID") and
this.isStatic() and
this.isFinal() and
this.getType().hasName("long") and
this.getDeclaringType().getASupertype*() instanceof TypeSerializable
}
}
@@ -104,7 +104,7 @@ class SerialVersionUIDField extends ReflectivelyReadField {
class LiveJaxbBoundField extends ReflectivelyReadField, JaxbBoundField {
LiveJaxbBoundField() {
// If the class is considered live, it must have at least one live constructor.
exists(Constructor c | c = getDeclaringType().getAConstructor() | isLive(c))
exists(Constructor c | c = this.getDeclaringType().getAConstructor() | isLive(c))
}
}
@@ -114,11 +114,11 @@ class LiveJaxbBoundField extends ReflectivelyReadField, JaxbBoundField {
*/
class JUnitAnnotatedField extends ReflectivelyReadField {
JUnitAnnotatedField() {
hasAnnotation("org.junit.experimental.theories", "DataPoint") or
hasAnnotation("org.junit.experimental.theories", "DataPoints") or
hasAnnotation("org.junit.runners", "Parameterized$Parameter") or
hasAnnotation("org.junit", "Rule") or
hasAnnotation("org.junit", "ClassRule")
this.hasAnnotation("org.junit.experimental.theories", "DataPoint") or
this.hasAnnotation("org.junit.experimental.theories", "DataPoints") or
this.hasAnnotation("org.junit.runners", "Parameterized$Parameter") or
this.hasAnnotation("org.junit", "Rule") or
this.hasAnnotation("org.junit", "ClassRule")
}
}
@@ -164,8 +164,8 @@ class JPAReadField extends ReflectivelyReadField {
)
|
not this.hasAnnotation("javax.persistence", "Transient") and
not isStatic() and
not isFinal()
not this.isStatic() and
not this.isFinal()
)
}
}

View File

@@ -102,7 +102,7 @@ library class JacksonReflectivelyConstructedClass extends ReflectivelyConstructe
override Callable getALiveCallable() {
// Constructors may be called by Jackson, if they are a no-arg, they have a suitable annotation,
// or inherit a suitable annotation through a mixin.
result = getAConstructor() and
result = this.getAConstructor() and
(
result.getNumberOfParameters() = 0 or
result.getAnAnnotation() instanceof JacksonAnnotation or
@@ -153,7 +153,7 @@ class DeserializedClass extends ReflectivelyConstructedClass {
*/
class NewInstanceCall extends EntryPoint, NewInstance {
override Constructor getALiveCallable() {
result = getInferredConstructor() and
result = this.getInferredConstructor() and
// The `newInstance(...)` call must be used in a live context.
isLive(this.getEnclosingCallable())
}
@@ -164,7 +164,7 @@ class NewInstanceCall extends EntryPoint, NewInstance {
*/
class ReflectiveMethodAccessEntryPoint extends EntryPoint, ReflectiveMethodAccess {
override Method getALiveCallable() {
result = inferAccessedMethod() and
result = this.inferAccessedMethod() and
// The `getMethod(...)` call must be used in a live context.
isLive(this.getEnclosingCallable())
}
@@ -210,8 +210,8 @@ class JaxbXmlEnum extends AnnotationEntryPoint {
class JaxbXmlType extends AnnotationEntryPoint, JaxbType {
override Callable getALiveCallable() {
// Must have a live no-arg constructor for JAXB to perform marshal/unmarshal.
exists(Constructor c | c = getAConstructor() and c.getNumberOfParameters() = 0 | isLive(c)) and
result = getACallable() and
exists(Constructor c | c = this.getAConstructor() and c.getNumberOfParameters() = 0 | isLive(c)) and
result = this.getACallable() and
(
// A bound getter or setter.
result instanceof JaxbBoundGetterSetter
@@ -262,7 +262,7 @@ class ManagedBeanImplEntryPoint extends EntryPoint, RegisteredManagedBeanImpl {
// Find the method that will be called for each method on each managed bean that this class
// implements.
this.inherits(result) and
result.(Method).overrides(getAnImplementedManagedBean().getAMethod())
result.overrides+(this.getAnImplementedManagedBean().getAMethod())
}
}
@@ -377,7 +377,7 @@ class JavaxResourceAnnotatedMethod extends CallableEntryPointOnConstructedClass
*/
class JavaxManagedBeanReflectivelyConstructed extends ReflectivelyConstructedClass {
JavaxManagedBeanReflectivelyConstructed() {
getAnAnnotation() instanceof JavaxManagedBeanAnnotation
this.getAnAnnotation() instanceof JavaxManagedBeanAnnotation
}
}
@@ -413,13 +413,13 @@ class PersistencePropertyMethod extends CallableEntryPoint {
*/
class PersistenceCallbackMethod extends CallableEntryPoint {
PersistenceCallbackMethod() {
getAnAnnotation() instanceof PrePersistAnnotation or
getAnAnnotation() instanceof PreRemoveAnnotation or
getAnAnnotation() instanceof PreUpdateAnnotation or
getAnAnnotation() instanceof PostPersistAnnotation or
getAnAnnotation() instanceof PostRemoveAnnotation or
getAnAnnotation() instanceof PostUpdateAnnotation or
getAnAnnotation() instanceof PostLoadAnnotation
this.getAnAnnotation() instanceof PrePersistAnnotation or
this.getAnAnnotation() instanceof PreRemoveAnnotation or
this.getAnAnnotation() instanceof PreUpdateAnnotation or
this.getAnAnnotation() instanceof PostPersistAnnotation or
this.getAnAnnotation() instanceof PostRemoveAnnotation or
this.getAnAnnotation() instanceof PostUpdateAnnotation or
this.getAnAnnotation() instanceof PostLoadAnnotation
}
}
@@ -429,20 +429,20 @@ class PersistenceCallbackMethod extends CallableEntryPoint {
*/
class ArbitraryXMLEntryPoint extends ReflectivelyConstructedClass {
ArbitraryXMLEntryPoint() {
fromSource() and
this.fromSource() and
exists(XMLAttribute attribute |
attribute.getName() = "className" or
attribute.getName().matches("%ClassName") or
attribute.getName() = "class" or
attribute.getName().matches("%Class")
|
attribute.getValue() = getQualifiedName()
attribute.getValue() = this.getQualifiedName()
)
}
override Callable getALiveCallable() {
// Any constructor on these classes, as we don't know which may be called.
result = getAConstructor()
result = this.getAConstructor()
}
}

View File

@@ -19,7 +19,7 @@ class Struts1ActionEntryPoint extends EntryPoint, Class {
exists(Method methodFromAction |
methodFromAction.getDeclaringType().hasQualifiedName("org.apache.struts.action", "Action")
|
result.(Method).overrides(methodFromAction)
result.(Method).overrides+(methodFromAction)
)
or
this.getASupertype*().hasQualifiedName("org.apache.struts.actions", "DispatchAction") and

View File

@@ -18,7 +18,7 @@ class TestMethodEntry extends CallableEntryPoint {
or
exists(AnnotationType a | a = this.getAnAnnotation().getType() |
a.hasQualifiedName("org.junit.runners", "Parameterized$Parameters") and
getDeclaringType() instanceof ParameterizedJUnitTest
this.getDeclaringType() instanceof ParameterizedJUnitTest
)
}
}
@@ -28,12 +28,12 @@ class TestMethodEntry extends CallableEntryPoint {
*/
class BeforeOrAfterEntry extends CallableEntryPoint {
BeforeOrAfterEntry() {
getAnAnnotation() instanceof TestNGBeforeAnnotation or
getAnAnnotation() instanceof TestNGAfterAnnotation or
getAnAnnotation() instanceof BeforeAnnotation or
getAnAnnotation() instanceof BeforeClassAnnotation or
getAnAnnotation() instanceof AfterAnnotation or
getAnAnnotation() instanceof AfterClassAnnotation
this.getAnAnnotation() instanceof TestNGBeforeAnnotation or
this.getAnAnnotation() instanceof TestNGAfterAnnotation or
this.getAnAnnotation() instanceof BeforeAnnotation or
this.getAnAnnotation() instanceof BeforeClassAnnotation or
this.getAnAnnotation() instanceof AfterAnnotation or
this.getAnAnnotation() instanceof AfterClassAnnotation
}
}
@@ -44,7 +44,7 @@ class JUnitTheories extends CallableEntryPoint {
JUnitTheories() {
exists(AnnotationType a |
a = this.getAnAnnotation().getType() and
getDeclaringType() instanceof JUnitTheoryTest
this.getDeclaringType() instanceof JUnitTheoryTest
|
a.hasQualifiedName("org.junit.experimental.theories", "Theory") or
a.hasQualifiedName("org.junit.experimental.theories", "DataPoint") or
@@ -63,7 +63,7 @@ class JUnitDataPointField extends ReflectivelyReadField {
a.hasQualifiedName("org.junit.experimental.theories", "DataPoint") or
a.hasQualifiedName("org.junit.experimental.theories", "DataPoints")
) and
getDeclaringType() instanceof JUnitTheoryTest
this.getDeclaringType() instanceof JUnitTheoryTest
)
}
}
@@ -152,7 +152,7 @@ class CucumberConstructedClass extends ReflectivelyConstructedClass {
// Consider any constructor to be live - Cucumber calls a runtime-specified dependency
// injection framework (possibly an in-built one) to construct these instances, so any
// constructor could be called.
result = getAConstructor()
result = this.getAConstructor()
}
}

View File

@@ -29,7 +29,7 @@ class ServletConstructedClass extends ReflectivelyConstructedClass {
*/
class ServletListenerClass extends ReflectivelyConstructedClass {
ServletListenerClass() {
getAnAncestor() instanceof ServletWebXMLListenerType and
this.getAnAncestor() instanceof ServletWebXMLListenerType and
// If we have seen any `web.xml` files, this listener will be considered to be live only if it is
// referred to as a listener-class in at least one. If no `web.xml` files are found, we assume
// that XML extraction was not enabled, and therefore consider all listener classes as live.
@@ -47,7 +47,7 @@ class ServletListenerClass extends ReflectivelyConstructedClass {
*/
class ServletFilterClass extends ReflectivelyConstructedClass {
ServletFilterClass() {
getASupertype*().hasQualifiedName("javax.servlet", "Filter") and
this.getASupertype*().hasQualifiedName("javax.servlet", "Filter") and
// If we have seen any `web.xml` files, this filter will be considered to be live only if it is
// referred to as a filter-class in at least one. If no `web.xml` files are found, we assume
// that XML extraction was not enabled, and therefore consider all filter classes as live.

View File

@@ -189,10 +189,9 @@ private predicate flowStep(RelevantNode n1, RelevantNode n2) {
n2.(ImplicitInstanceAccess).getInstanceAccess().(OwnInstanceAccess).getEnclosingCallable() = c
)
or
exists(Field f |
f.getAnAssignedValue() = n1.asExpr() and
n2.asExpr().(FieldRead).getField() = f
)
n2.(FieldValueNode).getField().getAnAssignedValue() = n1.asExpr()
or
n2.asExpr().(FieldRead).getField() = n1.(FieldValueNode).getField()
or
exists(EnumType enum, Method getValue |
enum.getAnEnumConstant().getAnAssignedValue() = n1.asExpr() and

View File

@@ -94,10 +94,9 @@ private predicate step(Node n1, Node n2) {
n2.(ImplicitInstanceAccess).getInstanceAccess().(OwnInstanceAccess).getEnclosingCallable() = c
)
or
exists(Field f |
f.getAnAssignedValue() = n1.asExpr() and
n2.asExpr().(FieldRead).getField() = f
)
n2.(FieldValueNode).getField().getAnAssignedValue() = n1.asExpr()
or
n2.asExpr().(FieldRead).getField() = n1.(FieldValueNode).getField()
or
n2.asExpr().(CastExpr).getExpr() = n1.asExpr()
or
@@ -132,7 +131,7 @@ private predicate step(Node n1, Node n2) {
or
exists(Field v |
containerStep(n1.asExpr(), v.getAnAccess()) and
n2.asExpr() = v.getAnAccess()
n2.(FieldValueNode).getField() = v
)
}

View File

@@ -39,7 +39,10 @@ private Expr getRunnerArgument(MethodAccess ma, Method runmethod) {
or
getRunnerArgument(ma, runmethod).(CastExpr).getExpr() = result
or
getRunnerArgument(ma, runmethod).(VarAccess).getVariable().getAnAssignedValue() = result
pragma[only_bind_out](getRunnerArgument(ma, runmethod))
.(VarAccess)
.getVariable()
.getAnAssignedValue() = result
}
/**

View File

@@ -48,7 +48,7 @@ class CamelToBeanURI extends CamelToURI {
/**
* Gets the bean referenced by this URI.
*/
SpringBean getRefBean() { result.getBeanIdentifier() = getBeanIdentifier() }
SpringBean getRefBean() { result.getBeanIdentifier() = this.getBeanIdentifier() }
}
/**

View File

@@ -31,7 +31,7 @@ class GuiceProvider extends Interface {
* A method that overrides the `get` method on the interface `com.google.inject.Provider`.
*/
Method getAnOverridingGetMethod() {
exists(Method m | m.getSourceDeclaration() = getGetMethod() | result.overrides*(m))
exists(Method m | m.getSourceDeclaration() = this.getGetMethod() | result.overrides*(m))
}
}

View File

@@ -17,11 +17,11 @@ library class JAXBMarshalMethod extends Method {
}
class JaxbAnnotationType extends AnnotationType {
JaxbAnnotationType() { getPackage().getName() = "javax.xml.bind.annotation" }
JaxbAnnotationType() { this.getPackage().getName() = "javax.xml.bind.annotation" }
}
class JaxbAnnotated extends Annotatable {
JaxbAnnotated() { getAnAnnotation().getType() instanceof JaxbAnnotationType }
JaxbAnnotated() { this.getAnAnnotation().getType() instanceof JaxbAnnotationType }
predicate hasJaxbAnnotation(string name) { hasJaxbAnnotation(this, name) }
}
@@ -54,7 +54,7 @@ class JaxbType extends Class {
this.getAnAnnotation() = a and
a.getType().(JaxbAnnotationType).hasName("XmlAccessorType")
|
result.getAnAccess() = a.getValue("value").(VarAccess)
result.getAnAccess() = a.getValue("value")
)
}
@@ -62,8 +62,8 @@ class JaxbType extends Class {
* Gets the `XmlAccessType` associated with this class.
*/
XmlAccessType getXmlAccessType() {
if exists(getDeclaredAccessType())
then result = getDeclaredAccessType()
if exists(this.getDeclaredAccessType())
then result = this.getDeclaredAccessType()
else
// Default access type, if not specified.
result.isPublicMember()
@@ -81,22 +81,22 @@ class XmlAccessType extends EnumConstant {
/**
* All public getter/setter pairs and public fields will be bound.
*/
predicate isPublicMember() { getName() = "PUBLIC_MEMBER" }
predicate isPublicMember() { this.getName() = "PUBLIC_MEMBER" }
/**
* All non-static, non-transient fields will be bound.
*/
predicate isField() { getName() = "FIELD" }
predicate isField() { this.getName() = "FIELD" }
/**
* All getter/setter pairs will be bound.
*/
predicate isProperty() { getName() = "PROPERTY" }
predicate isProperty() { this.getName() = "PROPERTY" }
/**
* Nothing will be bound automatically.
*/
predicate isNone() { getName() = "NONE" }
predicate isNone() { this.getName() = "NONE" }
}
/**
@@ -105,10 +105,10 @@ class XmlAccessType extends EnumConstant {
*/
class JaxbMemberAnnotation extends JaxbAnnotationType {
JaxbMemberAnnotation() {
hasName("XmlElement") or
hasName("XmlAttribute") or
hasName("XmlElementRefs") or
hasName("XmlElements")
this.hasName("XmlElement") or
this.hasName("XmlAttribute") or
this.hasName("XmlElementRefs") or
this.hasName("XmlElements")
}
}
@@ -121,14 +121,14 @@ private predicate isTransient(Member m) { hasJaxbAnnotation(m, "XmlTransient") }
class JaxbBoundField extends Field {
JaxbBoundField() {
// Fields cannot be static, because JAXB creates instances.
not isStatic() and
not this.isStatic() and
// Fields cannot be final, because JAXB instantiates the object, then sets the properties.
not isFinal() and
not this.isFinal() and
// No transient fields are ever bound.
not isTransient(this) and
(
// Explicitly annotated to be bound.
exists(getAnAnnotation().getType().(JaxbMemberAnnotation))
exists(this.getAnAnnotation().getType().(JaxbMemberAnnotation))
or
// Within a JAXB type which has an `XmlAcessType` that binds this field.
exists(JaxbType type | this.getDeclaringType() = type |
@@ -136,7 +136,7 @@ class JaxbBoundField extends Field {
type.getXmlAccessType().isField()
or
// Only public fields are automatically bound in this access type.
type.getXmlAccessType().isPublicMember() and isPublic()
type.getXmlAccessType().isPublicMember() and this.isPublic()
)
)
}
@@ -157,7 +157,7 @@ library class GetterOrSetterMethod extends Method {
* Holds if this method has a "pair"ed method, e.g. whether there is an equivalent getter if this
* is a setter, and vice versa.
*/
predicate isProperty() { exists(getPair()) }
predicate isProperty() { exists(this.getPair()) }
/**
* Gets the "pair" method, if one exists; that is, the getter if this is a setter, and vice versa.
@@ -183,16 +183,16 @@ class JaxbBoundGetterSetter extends GetterOrSetterMethod {
this.getField() instanceof JaxbBoundField
or
// An annotation on this method or the pair that indicate that it is a valid setter/getter.
getThisOrPair().getAnAnnotation().getType() instanceof JaxbMemberAnnotation
this.getThisOrPair().getAnAnnotation().getType() instanceof JaxbMemberAnnotation
or
// Within a JAXB type which has an `XmlAcessType` that binds this method.
exists(JaxbType c | this.getDeclaringType() = c |
// If this is a "property" - both a setter and getter present for the XML element or attribute
// - the `XmlAccessType` of the declaring type may cause this property to be bound.
isProperty() and
this.isProperty() and
(
// In the `PUBLIC_MEMBER` case all public properties are considered bound.
c.getXmlAccessType().isPublicMember() and isPublic()
c.getXmlAccessType().isPublicMember() and this.isPublic()
or
// In "property" all properties are considered bound.
c.getXmlAccessType().isProperty()

View File

@@ -64,5 +64,5 @@ class RunWithAnnotation extends Annotation {
/**
* Gets the runner that will be used.
*/
Type getRunner() { result = getValue("value").(TypeLiteral).getReferencedType() }
Type getRunner() { result = this.getValue("value").(TypeLiteral).getReferencedType() }
}

View File

@@ -7,31 +7,31 @@ private import semmle.code.java.dataflow.DataFlow
private class ObjectMapper extends RefType {
ObjectMapper() {
getASupertype*().hasQualifiedName("com.fasterxml.jackson.databind", "ObjectMapper")
this.getASupertype*().hasQualifiedName("com.fasterxml.jackson.databind", "ObjectMapper")
}
}
/** A builder for building Jackson's `JsonMapper`. */
class MapperBuilder extends RefType {
MapperBuilder() {
hasQualifiedName("com.fasterxml.jackson.databind.cfg", "MapperBuilder<JsonMapper,Builder>")
this.hasQualifiedName("com.fasterxml.jackson.databind.cfg", "MapperBuilder<JsonMapper,Builder>")
}
}
private class JsonFactory extends RefType {
JsonFactory() { hasQualifiedName("com.fasterxml.jackson.core", "JsonFactory") }
JsonFactory() { this.hasQualifiedName("com.fasterxml.jackson.core", "JsonFactory") }
}
private class JsonParser extends RefType {
JsonParser() { hasQualifiedName("com.fasterxml.jackson.core", "JsonParser") }
JsonParser() { this.hasQualifiedName("com.fasterxml.jackson.core", "JsonParser") }
}
/** A type descriptor in Jackson libraries. For example, `java.lang.Class`. */
class JacksonTypeDescriptorType extends RefType {
JacksonTypeDescriptorType() {
this instanceof TypeClass or
hasQualifiedName("com.fasterxml.jackson.databind", "JavaType") or
hasQualifiedName("com.fasterxml.jackson.core.type", "TypeReference")
this.hasQualifiedName("com.fasterxml.jackson.databind", "JavaType") or
this.hasQualifiedName("com.fasterxml.jackson.core.type", "TypeReference")
}
}

View File

@@ -25,9 +25,7 @@ string getAJaxRsPackage(string subpackage) { result = getAJaxRsPackage() + "." +
class JaxWsEndpoint extends Class {
JaxWsEndpoint() {
exists(AnnotationType a | a = this.getAnAnnotation().getType() |
a.hasName("WebService") or
a.hasName("WebServiceProvider") or
a.hasName("WebServiceClient")
a.hasName(["WebService", "WebServiceProvider", "WebServiceClient"])
)
}
@@ -35,8 +33,7 @@ class JaxWsEndpoint extends Class {
Callable getARemoteMethod() {
result = this.getACallable() and
exists(AnnotationType a | a = result.getAnAnnotation().getType() |
a.hasName("WebMethod") or
a.hasName("WebEndpoint")
a.hasName(["WebMethod", "WebEndpoint"])
)
}
}
@@ -62,12 +59,7 @@ class JaxRsResourceMethod extends Method {
a = this.getAnAnnotation().getType() and
a.getPackage().getName() = getAJaxRsPackage()
|
a.hasName("GET") or
a.hasName("POST") or
a.hasName("DELETE") or
a.hasName("PUT") or
a.hasName("OPTIONS") or
a.hasName("HEAD")
a.hasName(["GET", "POST", "DELETE", "PUT", "OPTIONS", "HEAD"])
)
or
// A JaxRS resource method can also inherit these annotations from a supertype, but only if
@@ -201,13 +193,10 @@ class JaxRsInjectionAnnotation extends JaxRSAnnotation {
a = this.getType() and
a.getPackage().getName() = getAJaxRsPackage()
|
a.hasName("BeanParam") or
a.hasName("CookieParam") or
a.hasName("FormParam") or
a.hasName("HeaderParam") or
a.hasName("MatrixParam") or
a.hasName("PathParam") or
a.hasName("QueryParam")
a.hasName([
"BeanParam", "CookieParam", "FormParam", "HeaderParam", "MatrixParam", "PathParam",
"QueryParam"
])
)
or
this.getType().hasQualifiedName(getAJaxRsPackage("core"), "Context")

View File

@@ -41,39 +41,39 @@ class TypeLdapName extends Class {
/** A method with the name `addAll` declared in `javax.naming.ldap.LdapName`. */
class MethodLdapNameAddAll extends Method {
MethodLdapNameAddAll() {
getDeclaringType() instanceof TypeLdapName and
hasName("addAll")
this.getDeclaringType() instanceof TypeLdapName and
this.hasName("addAll")
}
}
/** A method with the name `clone` declared in `javax.naming.ldap.LdapName`. */
class MethodLdapNameClone extends Method {
MethodLdapNameClone() {
getDeclaringType() instanceof TypeLdapName and
hasName("clone")
this.getDeclaringType() instanceof TypeLdapName and
this.hasName("clone")
}
}
/** A method with the name `getAll` declared in `javax.naming.ldap.LdapName`. */
class MethodLdapNameGetAll extends Method {
MethodLdapNameGetAll() {
getDeclaringType() instanceof TypeLdapName and
hasName("getAll")
this.getDeclaringType() instanceof TypeLdapName and
this.hasName("getAll")
}
}
/** A method with the name `getRdns` declared in `javax.naming.ldap.LdapName`. */
class MethodLdapNameGetRdns extends Method {
MethodLdapNameGetRdns() {
getDeclaringType() instanceof TypeLdapName and
hasName("getRdns")
this.getDeclaringType() instanceof TypeLdapName and
this.hasName("getRdns")
}
}
/** A method with the name `toString` declared in `javax.naming.ldap.LdapName`. */
class MethodLdapNameToString extends Method {
MethodLdapNameToString() {
getDeclaringType() instanceof TypeLdapName and
hasName("toString")
this.getDeclaringType() instanceof TypeLdapName and
this.hasName("toString")
}
}

View File

@@ -11,8 +11,8 @@ private import semmle.code.java.dataflow.FlowSteps
*/
class Kryo extends RefType {
Kryo() {
hasQualifiedName("com.esotericsoftware.kryo", "Kryo") or
hasQualifiedName("com.esotericsoftware.kryo5", "Kryo")
this.hasQualifiedName("com.esotericsoftware.kryo", "Kryo") or
this.hasQualifiedName("com.esotericsoftware.kryo5", "Kryo")
}
}
@@ -21,8 +21,8 @@ class Kryo extends RefType {
*/
class KryoInput extends RefType {
KryoInput() {
hasQualifiedName("com.esotericsoftware.kryo.io", "Input") or
hasQualifiedName("com.esotericsoftware.kryo5.io", "Input")
this.hasQualifiedName("com.esotericsoftware.kryo.io", "Input") or
this.hasQualifiedName("com.esotericsoftware.kryo5.io", "Input")
}
}
@@ -31,8 +31,8 @@ class KryoInput extends RefType {
*/
class KryoPool extends RefType {
KryoPool() {
hasQualifiedName("com.esotericsoftware.kryo.pool", "KryoPool") or
hasQualifiedName("com.esotericsoftware.kryo5.pool", "KryoPool")
this.hasQualifiedName("com.esotericsoftware.kryo.pool", "KryoPool") or
this.hasQualifiedName("com.esotericsoftware.kryo5.pool", "KryoPool")
}
}
@@ -41,8 +41,8 @@ class KryoPool extends RefType {
*/
class KryoPoolBuilder extends RefType {
KryoPoolBuilder() {
hasQualifiedName("com.esotericsoftware.kryo.pool", "KryoPool$Builder") or
hasQualifiedName("com.esotericsoftware.kryo5.pool", "KryoPool$Builder")
this.hasQualifiedName("com.esotericsoftware.kryo.pool", "KryoPool$Builder") or
this.hasQualifiedName("com.esotericsoftware.kryo5.pool", "KryoPool$Builder")
}
}
@@ -51,10 +51,10 @@ class KryoPoolBuilder extends RefType {
*/
class KryoPoolBuilderMethod extends Method {
KryoPoolBuilderMethod() {
getDeclaringType() instanceof KryoPoolBuilder and
this.getDeclaringType() instanceof KryoPoolBuilder and
(
getReturnType() instanceof KryoPoolBuilder or
getReturnType() instanceof KryoPool
this.getReturnType() instanceof KryoPoolBuilder or
this.getReturnType() instanceof KryoPool
)
}
}
@@ -92,7 +92,7 @@ class KryoEnableWhiteListing extends MethodAccess {
*/
class KryoPoolRunMethod extends Method {
KryoPoolRunMethod() {
getDeclaringType() instanceof KryoPool and
hasName("run")
this.getDeclaringType() instanceof KryoPool and
this.hasName("run")
}
}

View File

@@ -11,8 +11,8 @@ import java
*/
class MockitoVerifyMethod extends Method {
MockitoVerifyMethod() {
getDeclaringType().getPackage().getName().matches("org.mockito%") and
hasName("verify")
this.getDeclaringType().getPackage().getName().matches("org.mockito%") and
this.hasName("verify")
}
}
@@ -21,7 +21,7 @@ class MockitoVerifyMethod extends Method {
*/
class MockitoVerifiedMethodAccess extends MethodAccess {
MockitoVerifiedMethodAccess() {
getQualifier().(MethodAccess).getMethod() instanceof MockitoVerifyMethod
this.getQualifier().(MethodAccess).getMethod() instanceof MockitoVerifyMethod
}
}
@@ -41,8 +41,8 @@ class MockitoMockableType extends ClassOrInterface {
*/
class MockitoInitMocks extends Method {
MockitoInitMocks() {
getDeclaringType().hasQualifiedName("org.mockito", "MockitoAnnotations") and
hasName("initMocks")
this.getDeclaringType().hasQualifiedName("org.mockito", "MockitoAnnotations") and
this.hasName("initMocks")
}
}
@@ -61,10 +61,10 @@ class MockitoInitedTest extends Class {
or
// Call to `MockitoAnnotations.initMocks()`, either by the constructor or by a `@Before` method.
exists(MockitoInitMocks initMocks |
getAConstructor().calls*(initMocks)
this.getAConstructor().calls*(initMocks)
or
exists(Method m |
m = getAnAncestor().getAMethod() and
m = this.getAnAncestor().getAMethod() and
(
m.hasAnnotation("org.junit", "Before") or
m.hasAnnotation("org.testng.annotations", "BeforeMethod")
@@ -85,8 +85,8 @@ class MockitoInitedTest extends Class {
*/
class MockitoAnnotation extends Annotation {
MockitoAnnotation() {
getType().getPackage().getName().matches("org.mockito") or
getType().getPackage().getName().matches("org.mockito.%")
this.getType().getPackage().getName().matches("org.mockito") or
this.getType().getPackage().getName().matches("org.mockito.%")
}
}
@@ -95,11 +95,11 @@ class MockitoAnnotation extends Annotation {
*/
class MockitoExclusiveAnnotation extends MockitoAnnotation {
MockitoExclusiveAnnotation() {
getType().hasQualifiedName("org.mockito", "Mock") or
getType().hasQualifiedName("org.mockito", "MockitoAnnotations$Mock") or
getType().hasQualifiedName("org.mockito", "InjectMocks") or
getType().hasQualifiedName("org.mockito", "Spy") or
getType().hasQualifiedName("org.mockito", "Captor")
this.getType().hasQualifiedName("org.mockito", "Mock") or
this.getType().hasQualifiedName("org.mockito", "MockitoAnnotations$Mock") or
this.getType().hasQualifiedName("org.mockito", "InjectMocks") or
this.getType().hasQualifiedName("org.mockito", "Spy") or
this.getType().hasQualifiedName("org.mockito", "Captor")
}
}
@@ -107,16 +107,16 @@ class MockitoExclusiveAnnotation extends MockitoAnnotation {
* A field which has a Mockito annotation.
*/
class MockitoAnnotatedField extends Field {
MockitoAnnotatedField() { getAnAnnotation() instanceof MockitoAnnotation }
MockitoAnnotatedField() { this.getAnAnnotation() instanceof MockitoAnnotation }
/**
* Holds if this field will be processed by Mockito.
*/
predicate isValid() {
// Mockito annotations are never parsed if the test isn't properly initialized.
getDeclaringType() instanceof MockitoInitedTest and
this.getDeclaringType() instanceof MockitoInitedTest and
// There should only be one "exclusive" mockito annotation per field.
count(getAnAnnotation().(MockitoExclusiveAnnotation)) = 1
count(this.getAnAnnotation().(MockitoExclusiveAnnotation)) = 1
}
}
@@ -125,16 +125,16 @@ class MockitoAnnotatedField extends Field {
*/
class MockitoMockedField extends MockitoAnnotatedField {
MockitoMockedField() {
hasAnnotation("org.mockito", "Mock")
this.hasAnnotation("org.mockito", "Mock")
or
// Deprecated style.
hasAnnotation("org.mockito", "MockitoAnnotations$Mock")
this.hasAnnotation("org.mockito", "MockitoAnnotations$Mock")
}
override predicate isValid() {
super.isValid() and
// The type must also be mockable, otherwise it will not be initialized.
getType() instanceof MockitoMockableType
this.getType() instanceof MockitoMockableType
}
/**
@@ -142,12 +142,13 @@ class MockitoMockedField extends MockitoAnnotatedField {
*/
predicate isReferencedByInjection() {
exists(MockitoInjectedField injectedField |
injectedField.getDeclaringType() = getDeclaringType()
injectedField.getDeclaringType() = this.getDeclaringType()
|
// A `@Mock` is injected if it is used in one of the invoked callables (constructor or
// setter), or injected directly onto a field.
getType().(RefType).getAnAncestor() = injectedField.getAnInvokedCallable().getAParamType() or
getType().(RefType).getAnAncestor() = injectedField.getASetField().getType()
this.getType().(RefType).getAnAncestor() =
injectedField.getAnInvokedCallable().getAParamType() or
this.getType().(RefType).getAnAncestor() = injectedField.getASetField().getType()
)
}
}
@@ -156,25 +157,25 @@ class MockitoMockedField extends MockitoAnnotatedField {
* A field annotated with `@InjectMocks`.
*/
class MockitoInjectedField extends MockitoAnnotatedField {
MockitoInjectedField() { hasAnnotation("org.mockito", "InjectMocks") }
MockitoInjectedField() { this.hasAnnotation("org.mockito", "InjectMocks") }
override predicate isValid() {
super.isValid() and
(
// If we need to initialize the field, it is only valid if the type is a `Class` that is not
// local, is static if it is a nested class, and is not abstract.
exists(getInitializer())
exists(this.getInitializer())
or
exists(Class c | c = getType() |
exists(Class c | c = this.getType() |
not c.isLocal() and
(getType() instanceof NestedClass implies c.(NestedClass).isStatic()) and
(this.getType() instanceof NestedClass implies c.(NestedClass).isStatic()) and
not c.isAbstract()
)
) and
(
// If neither of these is true, then mockito will fail to initialize this field.
usingConstructorInjection() or
usingPropertyInjection()
this.usingConstructorInjection() or
this.usingPropertyInjection()
)
}
@@ -184,7 +185,8 @@ class MockitoInjectedField extends MockitoAnnotatedField {
* Note: this does not include the no-arg constructor.
*/
predicate usingConstructorInjection() {
not exists(getInitializer()) and exists(getMockInjectedClass().getAMostMockableConstructor())
not exists(this.getInitializer()) and
exists(this.getMockInjectedClass().getAMostMockableConstructor())
}
/**
@@ -194,10 +196,10 @@ class MockitoInjectedField extends MockitoAnnotatedField {
* constructor, in addition to any property.
*/
predicate usingPropertyInjection() {
not usingConstructorInjection() and
not this.usingConstructorInjection() and
(
exists(getInitializer()) or
exists(getMockInjectedClass().getNoArgsConstructor())
exists(this.getInitializer()) or
exists(this.getMockInjectedClass().getNoArgsConstructor())
)
}
@@ -212,18 +214,18 @@ class MockitoInjectedField extends MockitoAnnotatedField {
Callable getAnInvokedCallable() {
exists(MockitoMockInjectedClass mockInjectedClass |
// This is the type we are constructing/injecting.
mockInjectedClass = getType()
mockInjectedClass = this.getType()
|
if usingConstructorInjection()
if this.usingConstructorInjection()
then
// If there is no initializer for this field, and there is a most mockable constructor,
// then we are doing a parameterized injection of mocks into a most mockable constructor.
result = mockInjectedClass.getAMostMockableConstructor()
else
if usingPropertyInjection()
if this.usingPropertyInjection()
then
// We will call the no-arg constructor if the field wasn't initialized.
not exists(getInitializer()) and
not exists(this.getInitializer()) and
result = mockInjectedClass.getNoArgsConstructor()
or
// Perform property injection into setter fields, but only where there exists a mock
@@ -249,9 +251,9 @@ class MockitoInjectedField extends MockitoAnnotatedField {
* Field injection only occurs if property injection and not constructor injection is used.
*/
Field getASetField() {
if usingPropertyInjection()
if this.usingPropertyInjection()
then
result = getMockInjectedClass().getASetField() and
result = this.getMockInjectedClass().getASetField() and
exists(MockitoMockedField mockedField |
mockedField.getDeclaringType() = this.getDeclaringType() and
mockedField.isValid()
@@ -268,15 +270,15 @@ class MockitoInjectedField extends MockitoAnnotatedField {
* A field annotated with the Mockito `@Spy` annotation.
*/
class MockitoSpiedField extends MockitoAnnotatedField {
MockitoSpiedField() { hasAnnotation("org.mockito", "Spy") }
MockitoSpiedField() { this.hasAnnotation("org.mockito", "Spy") }
override predicate isValid() {
super.isValid() and
(
exists(getInitializer())
exists(this.getInitializer())
or
exists(Constructor c |
c = getType().(RefType).getAConstructor() and c.getNumberOfParameters() = 0
c = this.getType().(RefType).getAConstructor() and c.getNumberOfParameters() = 0
)
)
}
@@ -284,7 +286,7 @@ class MockitoSpiedField extends MockitoAnnotatedField {
/**
* Holds if construction ever occurs.
*/
predicate isConstructed() { not exists(getInitializer()) }
predicate isConstructed() { not exists(this.getInitializer()) }
}
private int mockableParameterCount(Constructor constructor) {
@@ -312,8 +314,8 @@ library class MockitoMockInjectedClass extends Class {
* Mockito will call only one of them, but which one is dependent on the JVM...
*/
Constructor getAMostMockableConstructor() {
result = getAConstructor() and
mockableParameterCount(result) = max(mockableParameterCount(getAConstructor())) and
result = this.getAConstructor() and
mockableParameterCount(result) = max(mockableParameterCount(this.getAConstructor())) and
result.getNumberOfParameters() > 0
}
@@ -331,7 +333,7 @@ library class MockitoMockInjectedClass extends Class {
* it sets.
*/
Method getASetterMethod() {
result = getAMethod() and
result = this.getAMethod() and
exists(MockitoSettableField settableField | result = settableField.getSetterMethod())
}
@@ -342,7 +344,7 @@ library class MockitoMockInjectedClass extends Class {
* setter method.
*/
MockitoSettableField getASetField() {
result = getAField() and
result = this.getAField() and
not exists(result.getSetterMethod())
}
}
@@ -353,8 +355,8 @@ library class MockitoMockInjectedClass extends Class {
*/
class MockitoSettableField extends Field {
MockitoSettableField() {
not isFinal() and
not isStatic() and
not this.isFinal() and
not this.isStatic() and
exists(MockitoMockInjectedClass injectedClass | injectedClass = this.getDeclaringType())
}

View File

@@ -6,39 +6,39 @@ import semmle.code.java.Type
/** The type `java.net.URLConnection`. */
class TypeUrlConnection extends RefType {
TypeUrlConnection() { hasQualifiedName("java.net", "URLConnection") }
TypeUrlConnection() { this.hasQualifiedName("java.net", "URLConnection") }
}
/** The type `java.net.Socket`. */
class TypeSocket extends RefType {
TypeSocket() { hasQualifiedName("java.net", "Socket") }
TypeSocket() { this.hasQualifiedName("java.net", "Socket") }
}
/** The type `java.net.URL`. */
class TypeUrl extends RefType {
TypeUrl() { hasQualifiedName("java.net", "URL") }
TypeUrl() { this.hasQualifiedName("java.net", "URL") }
}
/** The type `java.net.URI`. */
class TypeUri extends RefType {
TypeUri() { hasQualifiedName("java.net", "URI") }
TypeUri() { this.hasQualifiedName("java.net", "URI") }
}
/** The method `java.net.URLConnection::getInputStream`. */
class URLConnectionGetInputStreamMethod extends Method {
URLConnectionGetInputStreamMethod() {
getDeclaringType() instanceof TypeUrlConnection and
hasName("getInputStream") and
hasNoParameters()
this.getDeclaringType() instanceof TypeUrlConnection and
this.hasName("getInputStream") and
this.hasNoParameters()
}
}
/** The method `java.net.Socket::getInputStream`. */
class SocketGetInputStreamMethod extends Method {
SocketGetInputStreamMethod() {
getDeclaringType() instanceof TypeSocket and
hasName("getInputStream") and
hasNoParameters()
this.getDeclaringType() instanceof TypeSocket and
this.hasName("getInputStream") and
this.hasNoParameters()
}
}

View File

@@ -7,13 +7,22 @@ private class OptionalModel extends SummaryModelCsv {
s =
[
"java.util;Optional;false;filter;;;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Optional;false;filter;;;Element of Argument[-1];Parameter[0] of Argument[0];value",
"java.util;Optional;false;flatMap;;;Element of Argument[-1];Parameter[0] of Argument[0];value",
"java.util;Optional;false;flatMap;;;ReturnValue of Argument[0];ReturnValue;value",
"java.util;Optional;false;get;;;Element of Argument[-1];ReturnValue;value",
"java.util;Optional;false;ifPresent;;;Element of Argument[-1];Parameter[0] of Argument[0];value",
"java.util;Optional;false;ifPresentOrElse;;;Element of Argument[-1];Parameter[0] of Argument[0];value",
"java.util;Optional;false;map;;;Element of Argument[-1];Parameter[0] of Argument[0];value",
"java.util;Optional;false;map;;;ReturnValue of Argument[0];Element of ReturnValue;value",
"java.util;Optional;false;of;;;Argument[0];Element of ReturnValue;value",
"java.util;Optional;false;ofNullable;;;Argument[0];Element of ReturnValue;value",
"java.util;Optional;false;or;;;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Optional;false;or;;;ReturnValue of Argument[0];ReturnValue;value",
"java.util;Optional;false;orElse;;;Element of Argument[-1];ReturnValue;value",
"java.util;Optional;false;orElse;;;Argument[0];ReturnValue;value",
"java.util;Optional;false;orElseGet;;;Element of Argument[-1];ReturnValue;value",
"java.util;Optional;false;orElseGet;;;ReturnValue of Argument[0];ReturnValue;value",
"java.util;Optional;false;orElseThrow;;;Element of Argument[-1];ReturnValue;value",
"java.util;Optional;false;stream;;;Element of Argument[-1];Element of ReturnValue;value"
]

View File

@@ -30,7 +30,7 @@ class ProtobufMessageLite extends Interface {
* Gets a static method named `parseFrom` (or similar) declared on a subtype of the `MessageLite` interface.
*/
Method getAParseFromMethod() {
result = getASubtype+().getAMethod() and
result = this.getASubtype+().getAMethod() and
result.getName().matches("parse%From") and
result.isStatic()
}
@@ -40,13 +40,7 @@ class ProtobufMessageLite extends Interface {
*/
Method getAGetterMethod() {
exists(RefType decl | decl = result.getDeclaringType() and decl = this.getASubtype+() |
exists(string name, string suffix |
suffix = "" or
suffix = "list" or
suffix = "map" or
suffix = "ordefault" or
suffix = "orthrow"
|
exists(string name, string suffix | suffix = ["", "list", "map", "ordefault", "orthrow"] |
exists(Field f | f.getDeclaringType() = decl |
f.getName().toLowerCase().replaceAll("_", "") = name
) and

View File

@@ -74,7 +74,7 @@ library class HttpServletRequestGetQueryStringMethod extends Method {
/**
* The method `getPathInfo()` declared in `javax.servlet.http.HttpServletRequest`.
*/
library class HttpServletRequestGetPathMethod extends Method {
class HttpServletRequestGetPathMethod extends Method {
HttpServletRequestGetPathMethod() {
getDeclaringType() instanceof HttpServletRequest and
hasName("getPathInfo") and
@@ -120,7 +120,7 @@ library class HttpServletRequestGetHeaderNamesMethod extends Method {
/**
* The method `getRequestURL()` declared in `javax.servlet.http.HttpServletRequest`.
*/
library class HttpServletRequestGetRequestURLMethod extends Method {
class HttpServletRequestGetRequestURLMethod extends Method {
HttpServletRequestGetRequestURLMethod() {
getDeclaringType() instanceof HttpServletRequest and
hasName("getRequestURL") and
@@ -131,7 +131,7 @@ library class HttpServletRequestGetRequestURLMethod extends Method {
/**
* The method `getRequestURI()` declared in `javax.servlet.http.HttpServletRequest`.
*/
library class HttpServletRequestGetRequestURIMethod extends Method {
class HttpServletRequestGetRequestURIMethod extends Method {
HttpServletRequestGetRequestURIMethod() {
getDeclaringType() instanceof HttpServletRequest and
hasName("getRequestURI") and
@@ -191,6 +191,16 @@ class HttpServletResponseSendErrorMethod extends Method {
}
}
/**
* The method `getRequestDispatcher(String)` declared in `javax.servlet.http.HttpServletRequest` or `javax.servlet.ServletRequest`.
*/
class ServletRequestGetRequestDispatcherMethod extends Method {
ServletRequestGetRequestDispatcherMethod() {
getDeclaringType() instanceof ServletRequest and
hasName("getRequestDispatcher")
}
}
/**
* The method `sendRedirect(String)` declared in `javax.servlet.http.HttpServletResponse`.
*/

View File

@@ -37,14 +37,14 @@ private class SafeYamlConstructionFlowConfig extends DataFlow2::Configuration {
src.asExpr() instanceof SafeSnakeYamlConstruction
}
override predicate isSink(DataFlow::Node sink) { sink = yamlClassInstanceExprArgument(_) }
override predicate isSink(DataFlow::Node sink) { sink = this.yamlClassInstanceExprArgument(_) }
private DataFlow::ExprNode yamlClassInstanceExprArgument(ClassInstanceExpr cie) {
cie.getConstructedType() instanceof Yaml and
result.getExpr() = cie.getArgument(0)
}
ClassInstanceExpr getSafeYaml() { hasFlowTo(yamlClassInstanceExprArgument(result)) }
ClassInstanceExpr getSafeYaml() { this.hasFlowTo(this.yamlClassInstanceExprArgument(result)) }
}
/**
@@ -70,13 +70,13 @@ private class SafeYamlFlowConfig extends DataFlow3::Configuration {
override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeYaml }
override predicate isSink(DataFlow::Node sink) { sink = yamlParseQualifier(_) }
override predicate isSink(DataFlow::Node sink) { sink = this.yamlParseQualifier(_) }
private DataFlow::ExprNode yamlParseQualifier(SnakeYamlParse syp) {
result.getExpr() = syp.getQualifier()
}
SnakeYamlParse getASafeSnakeYamlParse() { hasFlowTo(yamlParseQualifier(result)) }
SnakeYamlParse getASafeSnakeYamlParse() { this.hasFlowTo(this.yamlParseQualifier(result)) }
}
/**

View File

@@ -77,8 +77,8 @@ class TypeLdapOperations extends Interface {
*/
class MethodSpringLdapTemplateAuthenticate extends Method {
MethodSpringLdapTemplateAuthenticate() {
getDeclaringType() instanceof TypeSpringLdapTemplate and
hasName("authenticate")
this.getDeclaringType() instanceof TypeSpringLdapTemplate and
this.hasName("authenticate")
}
}
@@ -88,8 +88,8 @@ class MethodSpringLdapTemplateAuthenticate extends Method {
*/
class MethodSpringLdapTemplateFind extends Method {
MethodSpringLdapTemplateFind() {
getDeclaringType() instanceof TypeSpringLdapTemplate and
hasName("find")
this.getDeclaringType() instanceof TypeSpringLdapTemplate and
this.hasName("find")
}
}
@@ -99,8 +99,8 @@ class MethodSpringLdapTemplateFind extends Method {
*/
class MethodSpringLdapTemplateFindOne extends Method {
MethodSpringLdapTemplateFindOne() {
getDeclaringType() instanceof TypeSpringLdapTemplate and
hasName("findOne")
this.getDeclaringType() instanceof TypeSpringLdapTemplate and
this.hasName("findOne")
}
}
@@ -110,8 +110,8 @@ class MethodSpringLdapTemplateFindOne extends Method {
*/
class MethodSpringLdapTemplateSearch extends Method {
MethodSpringLdapTemplateSearch() {
getDeclaringType() instanceof TypeSpringLdapTemplate and
hasName("search")
this.getDeclaringType() instanceof TypeSpringLdapTemplate and
this.hasName("search")
}
}
@@ -121,8 +121,8 @@ class MethodSpringLdapTemplateSearch extends Method {
*/
class MethodSpringLdapTemplateSearchForContext extends Method {
MethodSpringLdapTemplateSearchForContext() {
getDeclaringType() instanceof TypeSpringLdapTemplate and
hasName("searchForContext")
this.getDeclaringType() instanceof TypeSpringLdapTemplate and
this.hasName("searchForContext")
}
}
@@ -132,8 +132,8 @@ class MethodSpringLdapTemplateSearchForContext extends Method {
*/
class MethodSpringLdapTemplateSearchForObject extends Method {
MethodSpringLdapTemplateSearchForObject() {
getDeclaringType() instanceof TypeSpringLdapTemplate and
hasName("searchForObject")
this.getDeclaringType() instanceof TypeSpringLdapTemplate and
this.hasName("searchForObject")
}
}
@@ -143,8 +143,8 @@ class MethodSpringLdapTemplateSearchForObject extends Method {
*/
class MethodSpringLdapQueryBuilderFilter extends Method {
MethodSpringLdapQueryBuilderFilter() {
getDeclaringType() instanceof TypeSpringLdapQueryBuilder and
hasName("filter")
this.getDeclaringType() instanceof TypeSpringLdapQueryBuilder and
this.hasName("filter")
}
}
@@ -154,8 +154,8 @@ class MethodSpringLdapQueryBuilderFilter extends Method {
*/
class MethodSpringLdapQueryBuilderBase extends Method {
MethodSpringLdapQueryBuilderBase() {
getDeclaringType() instanceof TypeSpringLdapQueryBuilder and
hasName("base")
this.getDeclaringType() instanceof TypeSpringLdapQueryBuilder and
this.hasName("base")
}
}
@@ -165,8 +165,8 @@ class MethodSpringLdapQueryBuilderBase extends Method {
*/
class MethodSpringLdapNameBuilderNewInstance extends Method {
MethodSpringLdapNameBuilderNewInstance() {
getDeclaringType() instanceof TypeSpringLdapNameBuilder and
hasName("newInstance")
this.getDeclaringType() instanceof TypeSpringLdapNameBuilder and
this.hasName("newInstance")
}
}
@@ -176,8 +176,8 @@ class MethodSpringLdapNameBuilderNewInstance extends Method {
*/
class MethodSpringLdapNameBuilderAdd extends Method {
MethodSpringLdapNameBuilderAdd() {
getDeclaringType() instanceof TypeSpringLdapNameBuilder and
hasName("add")
this.getDeclaringType() instanceof TypeSpringLdapNameBuilder and
this.hasName("add")
}
}
@@ -187,8 +187,8 @@ class MethodSpringLdapNameBuilderAdd extends Method {
*/
class MethodSpringLdapNameBuilderBuild extends Method {
MethodSpringLdapNameBuilderBuild() {
getDeclaringType() instanceof TypeSpringLdapNameBuilder and
hasName("build")
this.getDeclaringType() instanceof TypeSpringLdapNameBuilder and
this.hasName("build")
}
}
@@ -198,7 +198,7 @@ class MethodSpringLdapNameBuilderBuild extends Method {
*/
class MethodSpringLdapUtilsNewLdapName extends Method {
MethodSpringLdapUtilsNewLdapName() {
getDeclaringType() instanceof TypeSpringLdapUtils and
hasName("newLdapName")
this.getDeclaringType() instanceof TypeSpringLdapUtils and
this.hasName("newLdapName")
}
}

View File

@@ -54,7 +54,8 @@ private class StringSummaryCsv extends SummaryModelCsv {
"java.lang;StringBuffer;true;StringBuffer;(CharSequence);;Argument[0];Argument[-1];taint",
"java.lang;StringBuffer;true;StringBuffer;(String);;Argument[0];Argument[-1];taint",
"java.lang;StringBuilder;true;StringBuilder;;;Argument[0];Argument[-1];taint",
"java.lang;CharSequence;true;subSequence;;;Argument[-1];ReturnValue;taint"
"java.lang;CharSequence;true;subSequence;;;Argument[-1];ReturnValue;taint",
"java.lang;CharSequence;true;toString;;;Argument[-1];ReturnValue;taint"
]
}
}

View File

@@ -27,7 +27,7 @@ class ThriftIface extends Interface {
Method getAnImplementingMethod() {
result.getDeclaringType().(Class).getASupertype+() = this and
result.overrides(getAMethod()) and
result.overrides+(this.getAMethod()) and
not result.getFile() = this.getFile()
}
}

View File

@@ -35,79 +35,79 @@ class TypeUnboundIdLDAPConnection extends Class {
/** A method with the name `setBaseDN` declared in `com.unboundid.ldap.sdk.SearchRequest`. */
class MethodUnboundIdSearchRequestSetBaseDN extends Method {
MethodUnboundIdSearchRequestSetBaseDN() {
getDeclaringType() instanceof TypeUnboundIdSearchRequest and
hasName("setBaseDN")
this.getDeclaringType() instanceof TypeUnboundIdSearchRequest and
this.hasName("setBaseDN")
}
}
/** A method with the name `setFilter` declared in `com.unboundid.ldap.sdk.SearchRequest`. */
class MethodUnboundIdSearchRequestSetFilter extends Method {
MethodUnboundIdSearchRequestSetFilter() {
getDeclaringType() instanceof TypeUnboundIdSearchRequest and
hasName("setFilter")
this.getDeclaringType() instanceof TypeUnboundIdSearchRequest and
this.hasName("setFilter")
}
}
/** A method with the name `create` declared in `com.unboundid.ldap.sdk.Filter`. */
class MethodUnboundIdFilterCreate extends Method {
MethodUnboundIdFilterCreate() {
getDeclaringType() instanceof TypeUnboundIdLdapFilter and
hasName("create")
this.getDeclaringType() instanceof TypeUnboundIdLdapFilter and
this.hasName("create")
}
}
/** A method with the name `createANDFilter` declared in `com.unboundid.ldap.sdk.Filter`. */
class MethodUnboundIdFilterCreateANDFilter extends Method {
MethodUnboundIdFilterCreateANDFilter() {
getDeclaringType() instanceof TypeUnboundIdLdapFilter and
hasName("createANDFilter")
this.getDeclaringType() instanceof TypeUnboundIdLdapFilter and
this.hasName("createANDFilter")
}
}
/** A method with the name `createORFilter` declared in `com.unboundid.ldap.sdk.Filter`. */
class MethodUnboundIdFilterCreateORFilter extends Method {
MethodUnboundIdFilterCreateORFilter() {
getDeclaringType() instanceof TypeUnboundIdLdapFilter and
hasName("createORFilter")
this.getDeclaringType() instanceof TypeUnboundIdLdapFilter and
this.hasName("createORFilter")
}
}
/** A method with the name `createNOTFilter` declared in `com.unboundid.ldap.sdk.Filter`. */
class MethodUnboundIdFilterCreateNOTFilter extends Method {
MethodUnboundIdFilterCreateNOTFilter() {
getDeclaringType() instanceof TypeUnboundIdLdapFilter and
hasName("createNOTFilter")
this.getDeclaringType() instanceof TypeUnboundIdLdapFilter and
this.hasName("createNOTFilter")
}
}
/** A method with the name `simplifyFilter` declared in `com.unboundid.ldap.sdk.Filter`. */
class MethodUnboundIdFilterSimplifyFilter extends Method {
MethodUnboundIdFilterSimplifyFilter() {
getDeclaringType() instanceof TypeUnboundIdLdapFilter and
hasName("simplifyFilter")
this.getDeclaringType() instanceof TypeUnboundIdLdapFilter and
this.hasName("simplifyFilter")
}
}
/** A method with the name `search` declared in `com.unboundid.ldap.sdk.LDAPConnection`. */
class MethodUnboundIdLDAPConnectionSearch extends Method {
MethodUnboundIdLDAPConnectionSearch() {
getDeclaringType() instanceof TypeUnboundIdLDAPConnection and
hasName("search")
this.getDeclaringType() instanceof TypeUnboundIdLDAPConnection and
this.hasName("search")
}
}
/** A method with the name `asyncSearch` declared in `com.unboundid.ldap.sdk.LDAPConnection`. */
class MethodUnboundIdLDAPConnectionAsyncSearch extends Method {
MethodUnboundIdLDAPConnectionAsyncSearch() {
getDeclaringType() instanceof TypeUnboundIdLDAPConnection and
hasName("asyncSearch")
this.getDeclaringType() instanceof TypeUnboundIdLDAPConnection and
this.hasName("asyncSearch")
}
}
/** A method with the name `searchForEntry` declared in `com.unboundid.ldap.sdk.LDAPConnection`. */
class MethodUnboundIdLDAPConnectionSearchForEntry extends Method {
MethodUnboundIdLDAPConnectionSearchForEntry() {
getDeclaringType() instanceof TypeUnboundIdLDAPConnection and
hasName("searchForEntry")
this.getDeclaringType() instanceof TypeUnboundIdLDAPConnection and
this.hasName("searchForEntry")
}
}

View File

@@ -37,10 +37,12 @@ class AndroidComponent extends Class {
}
/** Holds if this Android component is configured as `exported` in an `AndroidManifest.xml` file. */
predicate isExported() { getAndroidComponentXmlElement().isExported() }
predicate isExported() { this.getAndroidComponentXmlElement().isExported() }
/** Holds if this Android component has an intent filter configured in an `AndroidManifest.xml` file. */
predicate hasIntentFilter() { exists(getAndroidComponentXmlElement().getAnIntentFilterElement()) }
predicate hasIntentFilter() {
exists(this.getAndroidComponentXmlElement().getAnIntentFilterElement())
}
}
/**
@@ -53,10 +55,10 @@ class ExportableAndroidComponent extends AndroidComponent {
* `AndroidManifest.xml` file.
*/
override predicate isExported() {
getAndroidComponentXmlElement().isExported()
this.getAndroidComponentXmlElement().isExported()
or
hasIntentFilter() and
not getAndroidComponentXmlElement().isNotExported()
this.hasIntentFilter() and
not this.getAndroidComponentXmlElement().isNotExported()
}
}
@@ -88,7 +90,7 @@ class AndroidContentProvider extends ExportableAndroidComponent {
* in an `AndroidManifest.xml` file.
*/
predicate requiresPermissions() {
getAndroidComponentXmlElement().(AndroidProviderXmlElement).requiresPermissions()
this.getAndroidComponentXmlElement().(AndroidProviderXmlElement).requiresPermissions()
}
}

View File

@@ -0,0 +1,52 @@
/** Provides classes and predicates to reason about `AsyncTask`s in Android. */
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.FlowSteps
/**
* Models the value-preserving step from `asyncTask.execute(params)` to `AsyncTask::doInBackground(params)`.
*/
private class AsyncTaskAdditionalValueStep extends AdditionalValueStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
exists(ExecuteAsyncTaskMethodAccess ma, AsyncTaskRunInBackgroundMethod m |
DataFlow::getInstanceArgument(ma).getType() = m.getDeclaringType() and
node1.asExpr() = ma.getParamsArgument() and
node2.asParameter() = m.getParameter(0)
)
}
}
/**
* The Android class `android.os.AsyncTask`.
*/
private class AsyncTask extends RefType {
AsyncTask() { this.hasQualifiedName("android.os", "AsyncTask") }
}
/** A call to the `execute` or `executeOnExecutor` methods of the `android.os.AsyncTask` class. */
private class ExecuteAsyncTaskMethodAccess extends MethodAccess {
Argument paramsArgument;
ExecuteAsyncTaskMethodAccess() {
exists(Method m |
this.getMethod() = m and
m.getDeclaringType().getSourceDeclaration().getASourceSupertype*() instanceof AsyncTask
|
m.getName() = "execute" and not m.isStatic() and paramsArgument = this.getArgument(0)
or
m.getName() = "executeOnExecutor" and paramsArgument = this.getArgument(1)
)
}
/** Returns the `params` argument of this call. */
Argument getParamsArgument() { result = paramsArgument }
}
/** The `doInBackground` method of the `android.os.AsyncTask` class. */
private class AsyncTaskRunInBackgroundMethod extends Method {
AsyncTaskRunInBackgroundMethod() {
this.getDeclaringType().getSourceDeclaration().getASourceSupertype*() instanceof AsyncTask and
this.getName() = "doInBackground"
}
}

View File

@@ -7,35 +7,42 @@ import semmle.code.java.dataflow.ExternalFlow
* The class `android.content.Intent`.
*/
class TypeIntent extends Class {
TypeIntent() { hasQualifiedName("android.content", "Intent") }
TypeIntent() { this.hasQualifiedName("android.content", "Intent") }
}
/** The class `android.content.ComponentName`. */
class TypeComponentName extends Class {
TypeComponentName() { this.hasQualifiedName("android.content", "ComponentName") }
}
/**
* The class `android.app.Activity`.
*/
class TypeActivity extends Class {
TypeActivity() { hasQualifiedName("android.app", "Activity") }
TypeActivity() { this.hasQualifiedName("android.app", "Activity") }
}
/**
* The class `android.content.Context`.
*/
class TypeContext extends RefType {
TypeContext() { hasQualifiedName("android.content", "Context") }
TypeContext() { this.hasQualifiedName("android.content", "Context") }
}
/**
* The class `android.content.BroadcastReceiver`.
*/
class TypeBroadcastReceiver extends Class {
TypeBroadcastReceiver() { hasQualifiedName("android.content", "BroadcastReceiver") }
TypeBroadcastReceiver() { this.hasQualifiedName("android.content", "BroadcastReceiver") }
}
/**
* The method `Activity.getIntent`
*/
class AndroidGetIntentMethod extends Method {
AndroidGetIntentMethod() { hasName("getIntent") and getDeclaringType() instanceof TypeActivity }
AndroidGetIntentMethod() {
this.hasName("getIntent") and this.getDeclaringType() instanceof TypeActivity
}
}
/**
@@ -43,7 +50,7 @@ class AndroidGetIntentMethod extends Method {
*/
class AndroidReceiveIntentMethod extends Method {
AndroidReceiveIntentMethod() {
hasName("onReceive") and getDeclaringType() instanceof TypeBroadcastReceiver
this.hasName("onReceive") and this.getDeclaringType() instanceof TypeBroadcastReceiver
}
}
@@ -52,8 +59,8 @@ class AndroidReceiveIntentMethod extends Method {
*/
class ContextStartActivityMethod extends Method {
ContextStartActivityMethod() {
(hasName("startActivity") or hasName("startActivities")) and
getDeclaringType() instanceof TypeContext
(this.hasName("startActivity") or this.hasName("startActivities")) and
this.getDeclaringType() instanceof TypeContext
}
}
@@ -70,11 +77,66 @@ private class IntentFieldsInheritTaint extends DataFlow::SyntheticFieldContent,
*/
class IntentGetParcelableExtraMethod extends Method {
IntentGetParcelableExtraMethod() {
hasName("getParcelableExtra") and
getDeclaringType() instanceof TypeIntent
this.hasName("getParcelableExtra") and
this.getDeclaringType() instanceof TypeIntent
}
}
/** The class `android.os.BaseBundle`, or a class that extends it. */
class AndroidBundle extends Class {
AndroidBundle() { this.getASupertype*().hasQualifiedName("android.os", "BaseBundle") }
}
/** An `Intent` that explicitly sets a destination component. */
class ExplicitIntent extends Expr {
ExplicitIntent() {
exists(MethodAccess ma, Method m |
ma.getMethod() = m and
m.getDeclaringType() instanceof TypeIntent and
m.hasName(["setPackage", "setClass", "setClassName", "setComponent"]) and
ma.getQualifier() = this
)
or
exists(ConstructorCall cc, Argument classArg |
cc.getConstructedType() instanceof TypeIntent and
cc.getAnArgument() = classArg and
classArg.getType() instanceof TypeClass and
not exists(NullLiteral nullLiteral | DataFlow::localExprFlow(nullLiteral, classArg)) and
cc = this
)
}
}
/**
* A sanitizer for explicit intents.
*
* Use this when you want to work only with implicit intents
* in a `DataFlow` or `TaintTracking` configuration.
*/
class ExplicitIntentSanitizer extends DataFlow::Node {
ExplicitIntentSanitizer() {
exists(ExplicitIntent explIntent | DataFlow::localExprFlow(explIntent, this.asExpr()))
}
}
private class BundleExtrasSyntheticField extends SyntheticField {
BundleExtrasSyntheticField() { this = "android.content.Intent.extras" }
override RefType getType() { result instanceof AndroidBundle }
}
/**
* Holds if extras may be implicitly read from the Intent `node`.
*/
predicate allowIntentExtrasImplicitRead(DataFlow::Node node, DataFlow::Content c) {
node.getType() instanceof TypeIntent and
(
c instanceof DataFlow::MapValueContent
or
c.(DataFlow::SyntheticFieldContent).getType() instanceof AndroidBundle
)
}
private class IntentBundleFlowSteps extends SummaryModelCsv {
override predicate row(string row) {
row =
@@ -236,3 +298,34 @@ private class IntentBundleFlowSteps extends SummaryModelCsv {
]
}
}
private class IntentComponentTaintSteps extends SummaryModelCsv {
override predicate row(string s) {
s =
[
"android.content;Intent;true;Intent;(Intent);;Argument[0];Argument[-1];taint",
"android.content;Intent;true;Intent;(Context,Class);;Argument[1];Argument[-1];taint",
"android.content;Intent;true;Intent;(String,Uri,Context,Class);;Argument[3];Argument[-1];taint",
"android.content;Intent;true;getIntent;(String);;Argument[0];ReturnValue;taint",
"android.content;Intent;true;getIntentOld;(String);;Argument[0];ReturnValue;taint",
"android.content;Intent;true;parseUri;(String,int);;Argument[0];ReturnValue;taint",
"android.content;Intent;true;setPackage;;;Argument[0];Argument[-1];taint",
"android.content;Intent;true;setClass;;;Argument[1];Argument[-1];taint",
"android.content;Intent;true;setClassName;(Context,String);;Argument[1];Argument[-1];taint",
"android.content;Intent;true;setClassName;(String,String);;Argument[0..1];Argument[-1];taint",
"android.content;Intent;true;setComponent;;;Argument[0];Argument[-1];taint",
"android.content;ComponentName;false;ComponentName;(String,String);;Argument[0..1];Argument[-1];taint",
"android.content;ComponentName;false;ComponentName;(Context,String);;Argument[1];Argument[-1];taint",
"android.content;ComponentName;false;ComponentName;(Context,Class);;Argument[1];Argument[-1];taint",
"android.content;ComponentName;false;ComponentName;(Parcel);;Argument[0];Argument[-1];taint",
"android.content;ComponentName;false;createRelative;(String,String);;Argument[0..1];ReturnValue;taint",
"android.content;ComponentName;false;createRelative;(Context,String);;Argument[1];ReturnValue;taint",
"android.content;ComponentName;false;flattenToShortString;;;Argument[-1];ReturnValue;taint",
"android.content;ComponentName;false;flattenToString;;;Argument[-1];ReturnValue;taint",
"android.content;ComponentName;false;getClassName;;;Argument[-1];ReturnValue;taint",
"android.content;ComponentName;false;getPackageName;;;Argument[-1];ReturnValue;taint",
"android.content;ComponentName;false;getShortClassName;;;Argument[-1];ReturnValue;taint",
"android.content;ComponentName;false;unflattenFromString;;;Argument[0];ReturnValue;taint"
]
}
}

View File

@@ -1,15 +1,15 @@
import java
class TypeWebView extends Class {
TypeWebView() { hasQualifiedName("android.webkit", "WebView") }
TypeWebView() { this.hasQualifiedName("android.webkit", "WebView") }
}
class TypeWebViewClient extends Class {
TypeWebViewClient() { hasQualifiedName("android.webkit", "WebViewClient") }
TypeWebViewClient() { this.hasQualifiedName("android.webkit", "WebViewClient") }
}
class TypeWebSettings extends Class {
TypeWebSettings() { hasQualifiedName("android.webkit", "WebSettings") }
TypeWebSettings() { this.hasQualifiedName("android.webkit", "WebSettings") }
}
class WebViewGetSettingsMethod extends Method {

View File

@@ -0,0 +1,34 @@
/** Definitions related to the Apache Commons IO library. */
import java
private import semmle.code.java.dataflow.ExternalFlow
private class CommonsIOSummaryCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.io;IOUtils;false;buffer;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;copy;;;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;copyLarge;;;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;read;;;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,byte[]);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,ByteBuffer);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;readFully;(ReadableByteChannel,ByteBuffer);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(Reader,char[],int,int);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readFully;(Reader,char[]);;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;readLines;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toBufferedInputStream;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toBufferedReader;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toByteArray;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toCharArray;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toInputStream;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;toString;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;write;;;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;writeChunked;;;Argument[0];Argument[1];taint",
"org.apache.commons.io;IOUtils;false;writeLines;;;Argument[0];Argument[2];taint",
"org.apache.commons.io;IOUtils;false;writeLines;;;Argument[1];Argument[2];taint"
]
}
}

View File

@@ -25,14 +25,14 @@ private class TypeLiteralToParseAsFlowConfiguration extends DataFlowForSerializa
)
}
TypeLiteral getSourceWithFlowToParseAs() { hasFlow(DataFlow::exprNode(result), _) }
TypeLiteral getSourceWithFlowToParseAs() { this.hasFlow(DataFlow::exprNode(result), _) }
}
/** A field that is deserialized by `HttpResponse.parseAs`. */
class HttpResponseParseAsDeserializableField extends DeserializableField {
HttpResponseParseAsDeserializableField() {
exists(RefType decltype, TypeLiteralToParseAsFlowConfiguration conf |
decltype = getDeclaringType() and
decltype = this.getDeclaringType() and
conf.getSourceWithFlowToParseAs().getReferencedType() = decltype and
decltype.fromSource()
)

View File

@@ -38,7 +38,7 @@ class GwtEntryPointClass extends Class {
isGwtXmlIncluded()
implies
// The entry point is live if it is specified in a `*.gwt.xml` file.
exists(getAGwtXmlFile())
exists(this.getAGwtXmlFile())
}
}
@@ -48,7 +48,7 @@ class GwtEntryPointClass extends Class {
*/
class GwtCompilationUnit extends CompilationUnit {
GwtCompilationUnit() {
exists(GwtXmlFile f | getRelativePath().matches(f.getARelativeSourcePath() + "%"))
exists(GwtXmlFile f | this.getRelativePath().matches(f.getARelativeSourcePath() + "%"))
}
}

View File

@@ -12,57 +12,62 @@ import GwtUiBinderXml
* An annotation in the package `com.google.gwt.uibinder.client`.
*/
class GwtUiBinderClientAnnotation extends Annotation {
GwtUiBinderClientAnnotation() { getType().getPackage().hasName("com.google.gwt.uibinder.client") }
GwtUiBinderClientAnnotation() {
this.getType().getPackage().hasName("com.google.gwt.uibinder.client")
}
}
/**
* A `@com.google.gwt.uibinder.client.UiHandler` annotation.
*/
class GwtUiHandlerAnnotation extends GwtUiBinderClientAnnotation {
GwtUiHandlerAnnotation() { getType().hasName("UiHandler") }
GwtUiHandlerAnnotation() { this.getType().hasName("UiHandler") }
}
/**
* A `@com.google.gwt.uibinder.client.UiField` annotation.
*/
class GwtUiFieldAnnotation extends GwtUiBinderClientAnnotation {
GwtUiFieldAnnotation() { getType().hasName("UiField") }
GwtUiFieldAnnotation() { this.getType().hasName("UiField") }
}
/**
* A `@com.google.gwt.uibinder.client.UiTemplate` annotation.
*/
class GwtUiTemplateAnnotation extends GwtUiBinderClientAnnotation {
GwtUiTemplateAnnotation() { getType().hasName("UiTemplate") }
GwtUiTemplateAnnotation() { this.getType().hasName("UiTemplate") }
}
/**
* A `@com.google.gwt.uibinder.client.UiFactory` annotation.
*/
class GwtUiFactoryAnnotation extends GwtUiBinderClientAnnotation {
GwtUiFactoryAnnotation() { getType().hasName("UiFactory") }
GwtUiFactoryAnnotation() { this.getType().hasName("UiFactory") }
}
/**
* A `@com.google.gwt.uibinder.client.UiConstructor` annotation.
*/
class GwtUiConstructorAnnotation extends GwtUiBinderClientAnnotation {
GwtUiConstructorAnnotation() { getType().hasName("UiConstructor") }
GwtUiConstructorAnnotation() { this.getType().hasName("UiConstructor") }
}
/**
* A field that is reflectively written to, and read from, by the GWT UiBinder framework.
*/
class GwtUiField extends Field {
GwtUiField() { getAnAnnotation() instanceof GwtUiFieldAnnotation }
GwtUiField() { this.getAnAnnotation() instanceof GwtUiFieldAnnotation }
/**
* If true, the field must be filled before `UiBinder.createAndBindUi` is called.
* If false, `UiBinder.createAndBindUi` will fill the field.
*/
predicate isProvided() {
getAnAnnotation().(GwtUiFieldAnnotation).getValue("provided").(BooleanLiteral).getBooleanValue() =
true
this.getAnAnnotation()
.(GwtUiFieldAnnotation)
.getValue("provided")
.(BooleanLiteral)
.getBooleanValue() = true
}
}
@@ -70,14 +75,14 @@ class GwtUiField extends Field {
* A method called as a handler for events thrown by GWT widgets.
*/
class GwtUiHandler extends Method {
GwtUiHandler() { getAnAnnotation() instanceof GwtUiHandlerAnnotation }
GwtUiHandler() { this.getAnAnnotation() instanceof GwtUiHandlerAnnotation }
/**
* Gets the name of the field for which this handler is registered.
*/
string getFieldName() {
result =
getAnAnnotation()
this.getAnAnnotation()
.(GwtUiHandlerAnnotation)
.getValue("value")
.(CompileTimeConstantExpr)
@@ -89,7 +94,7 @@ class GwtUiHandler extends Method {
*/
GwtUiField getField() {
result = this.getDeclaringType().getAField() and
result.getName() = getFieldName()
result.getName() = this.getFieldName()
}
}
@@ -98,12 +103,12 @@ class GwtUiHandler extends Method {
* construct an instance of a class specified in a UiBinder XML file.
*/
class GwtUiFactory extends Method {
GwtUiFactory() { getAnAnnotation() instanceof GwtUiFactoryAnnotation }
GwtUiFactory() { this.getAnAnnotation() instanceof GwtUiFactoryAnnotation }
}
/**
* A constructor that may be called by the UiBinder framework as a result of a `GWT.create()` call.
*/
class GwtUiConstructor extends Constructor {
GwtUiConstructor() { getAnAnnotation() instanceof GwtUiConstructorAnnotation }
GwtUiConstructor() { this.getAnAnnotation() instanceof GwtUiConstructorAnnotation }
}

View File

@@ -36,8 +36,8 @@ class GwtComponentTemplateElement extends XMLElement {
*/
Class getClass() {
exists(string namespace |
namespace = getNamespace().getURI() and
result.getQualifiedName() = namespace.substring(11, namespace.length()) + "." + getName()
namespace = this.getNamespace().getURI() and
result.getQualifiedName() = namespace.substring(11, namespace.length()) + "." + this.getName()
)
}
}

Some files were not shown because too many files have changed in this diff Show More