Skip to content

Commit 6b58d11

Browse files
authored
Merge pull request github#13900 from atorralba/atorralba/java/jaxws-getaremotemethod-improv
Java: Improve `JaxWsEndpoint::getARemoteMethod`
2 parents 59de92c + 3f9701c commit 6b58d11

File tree

4 files changed

+182
-11
lines changed

4 files changed

+182
-11
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: 103 additions & 5 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
/**
@@ -23,16 +25,112 @@ string getAJaxRsPackage(string subpackage) { result = getAJaxRsPackage() + "." +
2325
*/
2426
class JaxWsEndpoint extends Class {
2527
JaxWsEndpoint() {
26-
exists(AnnotationType a | a = this.getAnAnnotation().getType() |
28+
exists(AnnotationType a | a = this.getAnAncestor().getAnAnnotation().getType() |
2729
a.hasName(["WebService", "WebServiceProvider", "WebServiceClient"])
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+
result.isPublic() and
41+
not result instanceof InitializerMethod and
42+
not exists(Annotation a | a = result.getAnAnnotation() |
43+
a.getType().hasQualifiedName(["javax", "jakarta"] + ".jws", "WebMethod") and
44+
a.getValue("exclude").(BooleanLiteral).getBooleanValue() = true
45+
) and
46+
forex(ParamOrReturn paramOrRet | paramOrRet = result.getAParameter() or paramOrRet = result |
47+
exists(Type t | t = paramOrRet.getType() |
48+
t instanceof JaxAcceptableType
49+
or
50+
t.(Annotatable).getAnAnnotation().getType() instanceof XmlJavaTypeAdapter
51+
or
52+
t instanceof VoidType
53+
)
54+
or
55+
paramOrRet.getInheritedAnnotation().getType() instanceof XmlJavaTypeAdapter
56+
)
57+
}
58+
}
59+
60+
/** The annotation type `@XmlJavaTypeAdapter`. */
61+
class XmlJavaTypeAdapter extends AnnotationType {
62+
XmlJavaTypeAdapter() {
63+
this.hasQualifiedName(["javax", "jakarta"] + ".xml.bind.annotation.adapters",
64+
"XmlJavaTypeAdapter")
65+
}
66+
}
67+
68+
private class ParamOrReturn extends Annotatable {
69+
ParamOrReturn() { this instanceof Parameter or this instanceof Method }
70+
71+
Type getType() {
72+
result = this.(Parameter).getType()
73+
or
74+
result = this.(Method).getReturnType()
75+
}
76+
77+
Annotation getInheritedAnnotation() {
78+
result = this.getAnAnnotation()
79+
or
80+
result = this.(Method).getAnOverride*().getAnAnnotation()
81+
or
82+
result =
83+
this.(Parameter)
84+
.getCallable()
85+
.(Method)
86+
.getAnOverride*()
87+
.getParameter(this.(Parameter).getPosition())
88+
.getAnAnnotation()
89+
}
90+
}
91+
92+
// JAX-RPC 1.1, section 5
93+
private class JaxAcceptableType extends Type {
94+
JaxAcceptableType() {
95+
// JAX-RPC 1.1, section 5.1.1
96+
this instanceof PrimitiveType
97+
or
98+
// JAX-RPC 1.1, section 5.1.2
99+
this.(Array).getElementType() instanceof JaxAcceptableType
100+
or
101+
// JAX-RPC 1.1, section 5.1.3
102+
this instanceof JaxAcceptableStandardClass
103+
or
104+
// JAX-RPC 1.1, section 5.1.4
105+
this instanceof JaxValueType
106+
}
107+
}
108+
109+
private class JaxAcceptableStandardClass extends RefType {
110+
JaxAcceptableStandardClass() {
111+
this instanceof TypeString or
112+
this.hasQualifiedName("java.util", "Date") or
113+
this.hasQualifiedName("java.util", "Calendar") or
114+
this.hasQualifiedName("java.math", "BigInteger") or
115+
this.hasQualifiedName("java.math", "BigDecimal") or
116+
this.hasQualifiedName("javax.xml.namespace", "QName") or
117+
this instanceof TypeUri
118+
}
119+
}
120+
121+
// JAX-RPC 1.1, section 5.4
122+
private class JaxValueType extends RefType {
123+
JaxValueType() {
124+
not this instanceof Wildcard and
125+
// Mutually exclusive with other `JaxAcceptableType`s
126+
not this instanceof Array and
127+
not this instanceof JaxAcceptableStandardClass and
128+
not this.getPackage().getName().matches("java.%") and
129+
// Must not implement (directly or indirectly) the java.rmi.Remote interface.
130+
not this.getAnAncestor() instanceof TypeRemote and
131+
// The Java type of a public field must be a supported JAX-RPC type as specified in the section 5.1.
132+
forall(Field f | this.getAMember() = f and f.isPublic() |
133+
f.getType() instanceof JaxAcceptableType
36134
)
37135
}
38136
}
Lines changed: 60 additions & 6 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;
@@ -8,37 +11,88 @@
811
class WebServiceClass { // $ JaxWsEndpoint
912

1013
@WebMethod
11-
void WebMethodMethod() { // $ JaxWsEndpointRemoteMethod
14+
public void WebMethodMethod() { // $ JaxWsEndpointRemoteMethod
1215
}
1316

1417
@WebEndpoint
15-
void WebEndpointMethod() { // $ JaxWsEndpointRemoteMethod
18+
public void WebEndpointMethod() { // $ JaxWsEndpointRemoteMethod
19+
}
20+
21+
public String acceptableTypes(String param) { // $ JaxWsEndpointRemoteMethod
22+
return null;
23+
}
24+
25+
public String unacceptableParamType(File param) { // not an endpoint
26+
return null;
27+
}
28+
29+
public File unacceptableReturnType() { // not an endpoint
30+
return null;
1631
}
1732

33+
@XmlJavaTypeAdapter
34+
public File annotatedTypes(@XmlJavaTypeAdapter File param) { // $ JaxWsEndpointRemoteMethod
35+
return null;
36+
}
1837
}
1938

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

2343
@WebMethod
24-
void WebMethodMethod() { // $ JaxWsEndpointRemoteMethod
44+
public void WebMethodMethod() { // $ JaxWsEndpointRemoteMethod
2545
}
2646

2747
@WebEndpoint
28-
void WebEndpointMethod() { // $ JaxWsEndpointRemoteMethod
48+
public void WebEndpointMethod() { // $ JaxWsEndpointRemoteMethod
49+
}
50+
51+
public String acceptableTypes(String param) { // $ JaxWsEndpointRemoteMethod
52+
return null;
53+
}
54+
55+
public String unacceptableParamType(File param) { // not an endpoint
56+
return null;
2957
}
3058

59+
public File unacceptableReturnType() { // not an endpoint
60+
return null;
61+
}
62+
63+
@XmlJavaTypeAdapter
64+
public File annotatedTypes(@XmlJavaTypeAdapter File param) { // $ JaxWsEndpointRemoteMethod
65+
return null;
66+
}
3167
}
3268

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

3673
@WebMethod
37-
void WebMethodMethod() { // $ JaxWsEndpointRemoteMethod
74+
public void WebMethodMethod() { // $ JaxWsEndpointRemoteMethod
3875
}
3976

4077
@WebEndpoint
41-
void WebEndpointMethod() { // $ JaxWsEndpointRemoteMethod
78+
public void WebEndpointMethod() { // $ JaxWsEndpointRemoteMethod
79+
}
80+
81+
public String acceptableTypes(String param) { // $ JaxWsEndpointRemoteMethod
82+
return null;
83+
}
84+
85+
public String unacceptableParamType(File param) { // not an endpoint
86+
return null;
87+
}
88+
89+
public File unacceptableReturnType() { // not an endpoint
90+
return null;
91+
}
92+
93+
@XmlJavaTypeAdapter
94+
public File annotatedTypes(@XmlJavaTypeAdapter File param) { // $ JaxWsEndpointRemoteMethod
95+
return null;
4296
}
4397

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)