Skip to content

Commit 43b9199

Browse files
committed
Java: Improved JaxWsEndpoint::getARemoteMethod
1 parent 2300285 commit 43b9199

File tree

4 files changed

+174
-4
lines changed

4 files changed

+174
-4
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The predicate `JaxWsEndpoint::getARemoteMethod` no longer requires the result to be annotated with `@WebMethod`. Instead, the requirements listed in the JAX-RPC Specification 1.1 for required parameter and return types are used. Applications using JAX-RS may see an increase in results.

java/ql/lib/semmle/code/java/frameworks/JaxWS.qll

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55

66
import java
7+
private import semmle.code.java.frameworks.Networking
8+
private import semmle.code.java.frameworks.Rmi
79
private import semmle.code.java.security.XSS
810

911
/**
@@ -28,11 +30,106 @@ class JaxWsEndpoint extends Class {
2830
)
2931
}
3032

31-
/** Gets a method annotated with `@WebMethod` or `@WebEndpoint`. */
32-
Callable getARemoteMethod() {
33+
/**
34+
* Gets a method of this class that is not an excluded `@WebMethod`,
35+
* and the parameters and return value of which are either of an acceptable type,
36+
* or are annotated with `@XmlJavaTypeAdapter`.
37+
*/
38+
Method getARemoteMethod() {
3339
result = this.getACallable() and
34-
exists(AnnotationType a | a = result.getAnAnnotation().getType() |
35-
a.hasName(["WebMethod", "WebEndpoint"])
40+
not result instanceof InitializerMethod and
41+
not exists(Annotation a | a = result.getAnAnnotation() |
42+
a.getType().hasQualifiedName(["javax", "jakarta"] + ".jws", "WebMethod") and
43+
a.getValue("exclude").(BooleanLiteral).getBooleanValue() = true
44+
) and
45+
forex(ParamOrReturn paramOrRet | paramOrRet = result.getAParameter() or paramOrRet = result |
46+
exists(Type t | t = paramOrRet.getType() |
47+
t instanceof JaxAcceptableType
48+
or
49+
t.(Annotatable).getAnAnnotation().getType() instanceof XmlJavaTypeAdapter
50+
or
51+
t instanceof VoidType
52+
)
53+
or
54+
paramOrRet.getInheritedAnnotation().getType() instanceof XmlJavaTypeAdapter
55+
)
56+
}
57+
}
58+
59+
/** The annotation type `@XmlJavaTypeAdapter`. */
60+
class XmlJavaTypeAdapter extends AnnotationType {
61+
XmlJavaTypeAdapter() {
62+
this.hasQualifiedName(["javax", "jakarta"] + ".xml.bind.annotation.adapters",
63+
"XmlJavaTypeAdapter")
64+
}
65+
}
66+
67+
private class ParamOrReturn extends Annotatable {
68+
ParamOrReturn() { this instanceof Parameter or this instanceof Method }
69+
70+
Type getType() {
71+
result = this.(Parameter).getType()
72+
or
73+
result = this.(Method).getReturnType()
74+
}
75+
76+
Annotation getInheritedAnnotation() {
77+
result = this.getAnAnnotation()
78+
or
79+
result = this.(Method).getAnOverride*().getAnAnnotation()
80+
or
81+
result =
82+
this.(Parameter)
83+
.getCallable()
84+
.(Method)
85+
.getAnOverride*()
86+
.getParameter(this.(Parameter).getPosition())
87+
.getAnAnnotation()
88+
}
89+
}
90+
91+
// JAX-RPC 1.1, section 5
92+
private class JaxAcceptableType extends Type {
93+
JaxAcceptableType() {
94+
// JAX-RPC 1.1, section 5.1.1
95+
this instanceof PrimitiveType
96+
or
97+
// JAX-RPC 1.1, section 5.1.2
98+
this.(Array).getElementType() instanceof JaxAcceptableType
99+
or
100+
// JAX-RPC 1.1, section 5.1.3
101+
this instanceof JaxAcceptableStandardClass
102+
or
103+
// JAX-RPC 1.1, section 5.1.4
104+
this instanceof JaxValueType
105+
}
106+
}
107+
108+
private class JaxAcceptableStandardClass extends RefType {
109+
JaxAcceptableStandardClass() {
110+
this instanceof TypeString or
111+
this.hasQualifiedName("java.util", "Date") or
112+
this.hasQualifiedName("java.util", "Calendar") or
113+
this.hasQualifiedName("java.math", "BigInteger") or
114+
this.hasQualifiedName("java.math", "BigDecimal") or
115+
this.hasQualifiedName("javax.xml.namespace", "QName") or
116+
this instanceof TypeUri
117+
}
118+
}
119+
120+
// JAX-RPC 1.1, section 5.4
121+
private class JaxValueType extends RefType {
122+
JaxValueType() {
123+
not this instanceof Wildcard and
124+
// Mutually exclusive with other `JaxAcceptableType`s
125+
not this instanceof Array and
126+
not this instanceof JaxAcceptableStandardClass and
127+
not this.getPackage().getName().matches("java.%") and
128+
// Must not implement (directly or indirectly) the java.rmi.Remote interface.
129+
not this.getAnAncestor() instanceof TypeRemote and
130+
// The Java type of a public field must be a supported JAX-RPC type as specified in the section 5.1.
131+
forall(Field f | this.getAMember() = f and f.isPublic() |
132+
f.getType() instanceof JaxAcceptableType
36133
)
37134
}
38135
}

java/ql/test/library-tests/frameworks/JaxWs/JaxWsEndpoint.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import java.io.File;
2+
13
import javax.jws.WebMethod;
24
import javax.jws.WebService;
5+
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
36
import javax.xml.ws.WebEndpoint;
47
import javax.xml.ws.WebServiceClient;
58
import javax.xml.ws.WebServiceProvider;
@@ -15,8 +18,25 @@ void WebMethodMethod() { // $ JaxWsEndpointRemoteMethod
1518
void WebEndpointMethod() { // $ JaxWsEndpointRemoteMethod
1619
}
1720

21+
String acceptableTypes(String param) { // $ JaxWsEndpointRemoteMethod
22+
return null;
23+
}
24+
25+
String unacceptableParamType(File param) { // not an endpoint
26+
return null;
27+
}
28+
29+
File unacceptableReturnType() { // not an endpoint
30+
return null;
31+
}
32+
33+
@XmlJavaTypeAdapter
34+
File annotatedTypes(@XmlJavaTypeAdapter File param) { // $ JaxWsEndpointRemoteMethod
35+
return null;
36+
}
1837
}
1938

39+
2040
@WebServiceProvider
2141
class WebServiceProviderClass { // $ JaxWsEndpoint
2242

@@ -28,8 +48,25 @@ void WebMethodMethod() { // $ JaxWsEndpointRemoteMethod
2848
void WebEndpointMethod() { // $ JaxWsEndpointRemoteMethod
2949
}
3050

51+
String acceptableTypes(String param) { // $ JaxWsEndpointRemoteMethod
52+
return null;
53+
}
54+
55+
String unacceptableParamType(File param) { // not an endpoint
56+
return null;
57+
}
58+
59+
File unacceptableReturnType() { // not an endpoint
60+
return null;
61+
}
62+
63+
@XmlJavaTypeAdapter
64+
File annotatedTypes(@XmlJavaTypeAdapter File param) { // $ JaxWsEndpointRemoteMethod
65+
return null;
66+
}
3167
}
3268

69+
3370
@WebServiceClient
3471
class WebServiceClientClass { // $ JaxWsEndpoint
3572

@@ -41,4 +78,21 @@ void WebMethodMethod() { // $ JaxWsEndpointRemoteMethod
4178
void WebEndpointMethod() { // $ JaxWsEndpointRemoteMethod
4279
}
4380

81+
String acceptableTypes(String param) { // $ JaxWsEndpointRemoteMethod
82+
return null;
83+
}
84+
85+
String unacceptableParamType(File param) { // not an endpoint
86+
return null;
87+
}
88+
89+
File unacceptableReturnType() { // not an endpoint
90+
return null;
91+
}
92+
93+
@XmlJavaTypeAdapter
94+
File annotatedTypes(@XmlJavaTypeAdapter File param) { // $ JaxWsEndpointRemoteMethod
95+
return null;
96+
}
97+
4498
}

java/ql/test/stubs/jaxws-api-2.0/javax/xml/bind/annotation/adapters/XmlJavaTypeAdapter.java

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)