diff --git a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qhelp b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qhelp
index 61b50a986e3..ce7f4751800 100644
--- a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qhelp
+++ b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qhelp
@@ -14,8 +14,8 @@ may have unforeseen effects, such as the execution of arbitrary code.
There are many different serialization frameworks. This query currently
-supports Kryo, XmlDecoder, XStream, SnakeYaml, and Java IO serialization through
-ObjectInputStream/ObjectOutputStream.
+supports Kryo, XmlDecoder, XStream, SnakeYaml, Hessian, JsonIO, YAMLBeans, Castor, Burlap,
+and Java IO serialization through ObjectInputStream/ObjectOutputStream.
@@ -75,6 +75,22 @@ Alvaro Muñoz & Christian Schneider, RSAConference 2016:
SnakeYaml documentation on deserialization:
SnakeYaml deserialization.
+
+Hessian deserialization and related gadget chains:
+Hessian deserialization.
+
+
+Castor and Hessian java deserialization vulnerabilities:
+Castor and Hessian deserialization.
+
+
+Remote code execution in JYaml library:
+JYaml deserialization.
+
+
+JsonIO deserialization vulnerabilities:
+JsonIO deserialization.
+
diff --git a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql
index bb4df03cd4f..3a77af853cf 100644
--- a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql
+++ b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql
@@ -21,6 +21,39 @@ class UnsafeDeserializationConfig extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserializationSink }
+
+ override predicate isAdditionalTaintStep(DataFlow::Node prod, DataFlow::Node succ) {
+ exists(ClassInstanceExpr cie |
+ cie.getConstructor().getDeclaringType() instanceof JsonReader and
+ cie.getArgument(0) = prod.asExpr() and
+ cie = succ.asExpr() and
+ not exists(SafeJsonIo sji | sji.hasFlowToExpr(cie.getArgument(1)))
+ )
+ or
+ exists(ClassInstanceExpr cie |
+ cie.getConstructor().getDeclaringType() instanceof YamlReader and
+ cie.getArgument(0) = prod.asExpr() and
+ cie = succ.asExpr()
+ )
+ or
+ exists(ClassInstanceExpr cie |
+ cie.getConstructor().getDeclaringType() instanceof UnSafeHessianInput and
+ cie.getArgument(0) = prod.asExpr() and
+ cie = succ.asExpr()
+ )
+ or
+ exists(ClassInstanceExpr cie |
+ cie.getConstructor().getDeclaringType() instanceof BurlapInput and
+ cie.getArgument(0) = prod.asExpr() and
+ cie = succ.asExpr()
+ )
+ or
+ exists(MethodAccess ma |
+ ma.getMethod() instanceof BurlapInputInitMethod and
+ ma.getArgument(0) = prod.asExpr() and
+ ma.getQualifier() = succ.asExpr()
+ )
+ }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, UnsafeDeserializationConfig conf
diff --git a/java/ql/src/semmle/code/java/frameworks/Castor.qll b/java/ql/src/semmle/code/java/frameworks/Castor.qll
new file mode 100644
index 00000000000..76abef7b5fe
--- /dev/null
+++ b/java/ql/src/semmle/code/java/frameworks/Castor.qll
@@ -0,0 +1,20 @@
+/**
+ * Provides classes and predicates for working with the Castor framework.
+ */
+
+import java
+
+/**
+ * The class `org.exolab.castor.xml.Unmarshaller`.
+ */
+class Unmarshaller extends RefType {
+ Unmarshaller() { this.hasQualifiedName("org.exolab.castor.xml", "Unmarshaller") }
+}
+
+/** A method with the name `unmarshal` declared in `org.exolab.castor.xml.Unmarshaller`. */
+class UnmarshalMethod extends Method {
+ UnmarshalMethod() {
+ this.getDeclaringType() instanceof Unmarshaller and
+ this.getName() = "unmarshal"
+ }
+}
diff --git a/java/ql/src/semmle/code/java/frameworks/Hessian.qll b/java/ql/src/semmle/code/java/frameworks/Hessian.qll
new file mode 100644
index 00000000000..78798d2b2fb
--- /dev/null
+++ b/java/ql/src/semmle/code/java/frameworks/Hessian.qll
@@ -0,0 +1,47 @@
+/**
+ * Provides classes and predicates for working with the Hession framework.
+ */
+
+import java
+
+/**
+ * The class `com.caucho.hessian.io.HessianInput` or `com.caucho.hessian.io.Hessian2Input`.
+ */
+class UnSafeHessianInput extends RefType {
+ UnSafeHessianInput() {
+ this.hasQualifiedName("com.caucho.hessian.io", ["HessianInput", "Hessian2Input"])
+ }
+}
+
+/**
+ * A HessianInput readObject method. This is either `HessianInput.readObject` or `Hessian2Input.readObject`.
+ */
+class UnSafeHessianInputReadObjectMethod extends Method {
+ UnSafeHessianInputReadObjectMethod() {
+ this.getDeclaringType() instanceof UnSafeHessianInput and
+ this.getName() = "readObject"
+ }
+}
+
+/**
+ * The class `com.caucho.burlap.io.BurlapInput`.
+ */
+class BurlapInput extends RefType {
+ BurlapInput() { this.hasQualifiedName("com.caucho.burlap.io", "BurlapInput") }
+}
+
+/** A method with the name `readObject` declared in `com.caucho.burlap.io.BurlapInput`. */
+class BurlapInputReadObjectMethod extends Method {
+ BurlapInputReadObjectMethod() {
+ this.getDeclaringType() instanceof BurlapInput and
+ this.getName() = "readObject"
+ }
+}
+
+/** A method with the name `init` declared in `com.caucho.burlap.io.BurlapInput`. */
+class BurlapInputInitMethod extends Method {
+ BurlapInputInitMethod() {
+ this.getDeclaringType() instanceof BurlapInput and
+ this.getName() = "init"
+ }
+}
diff --git a/java/ql/src/semmle/code/java/frameworks/JYaml.qll b/java/ql/src/semmle/code/java/frameworks/JYaml.qll
new file mode 100644
index 00000000000..bf523bec202
--- /dev/null
+++ b/java/ql/src/semmle/code/java/frameworks/JYaml.qll
@@ -0,0 +1,41 @@
+/**
+ * Provides classes and predicates for working with the JYaml framework.
+ */
+
+import java
+
+/**
+ * The class `org.ho.yaml.Yaml`.
+ */
+class JYaml extends RefType {
+ JYaml() { this.hasQualifiedName("org.ho.yaml", "Yaml") }
+}
+
+/**
+ * A JYaml unsafe load method. This is either `YAML.load` or
+ * `YAML.loadType` or `YAML.loadStream` or `YAML.loadStreamOfType`.
+ */
+class JYamlUnSafeLoadMethod extends Method {
+ JYamlUnSafeLoadMethod() {
+ this.getDeclaringType() instanceof JYaml and
+ this.getName() in ["load", "loadType", "loadStream", "loadStreamOfType"]
+ }
+}
+
+/**
+ * The class `org.ho.yaml.YamlConfig`.
+ */
+class JYamlConfig extends RefType {
+ JYamlConfig() { this.hasQualifiedName("org.ho.yaml", "YamlConfig") }
+}
+
+/**
+ * A JYamlConfig unsafe load method. This is either `YamlConfig.load` or
+ * `YAML.loadType` or `YamlConfig.loadStream` or `YamlConfig.loadStreamOfType`.
+ */
+class JYamlConfigUnSafeLoadMethod extends Method {
+ JYamlConfigUnSafeLoadMethod() {
+ this.getDeclaringType() instanceof JYamlConfig and
+ this.getName() in ["load", "loadType", "loadStream", "loadStreamOfType"]
+ }
+}
diff --git a/java/ql/src/semmle/code/java/frameworks/JsonIo.qll b/java/ql/src/semmle/code/java/frameworks/JsonIo.qll
new file mode 100644
index 00000000000..4170488f78d
--- /dev/null
+++ b/java/ql/src/semmle/code/java/frameworks/JsonIo.qll
@@ -0,0 +1,41 @@
+/**
+ * Provides classes and predicates for working with the Json-io framework.
+ */
+
+import java
+import semmle.code.java.Maps
+
+/**
+ * The class `com.cedarsoftware.util.io.JsonReader`.
+ */
+class JsonReader extends RefType {
+ JsonReader() { this.hasQualifiedName("com.cedarsoftware.util.io", "JsonReader") }
+}
+
+/** A method with the name `jsonToJava` declared in `com.cedarsoftware.util.io.JsonReader`. */
+class JsonIoJsonToJavaMethod extends Method {
+ JsonIoJsonToJavaMethod() {
+ this.getDeclaringType() instanceof JsonReader and
+ this.getName() = "jsonToJava"
+ }
+}
+
+/** A method with the name `readObject` declared in `com.cedarsoftware.util.io.JsonReader`. */
+class JsonIoReadObjectMethod extends Method {
+ JsonIoReadObjectMethod() {
+ this.getDeclaringType() instanceof JsonReader and
+ this.getName() = "readObject"
+ }
+}
+
+/**
+ * A call to `Map.put` method, set the value of the `USE_MAPS` key to `true`.
+ */
+class JsonIoSafeOptionalArgs extends MethodAccess {
+ JsonIoSafeOptionalArgs() {
+ this.getMethod().getDeclaringType().getASourceSupertype*() instanceof MapType and
+ this.getMethod().hasName("put") and
+ this.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "USE_MAPS" and
+ this.getArgument(1).(CompileTimeConstantExpr).getBooleanValue() = true
+ }
+}
diff --git a/java/ql/src/semmle/code/java/frameworks/YamlBeans.qll b/java/ql/src/semmle/code/java/frameworks/YamlBeans.qll
new file mode 100644
index 00000000000..63c282a80ec
--- /dev/null
+++ b/java/ql/src/semmle/code/java/frameworks/YamlBeans.qll
@@ -0,0 +1,20 @@
+/**
+ * Provides classes and predicates for working with the YamlBeans framework.
+ */
+
+import java
+
+/**
+ * The class `com.esotericsoftware.yamlbeans.YamlReader`.
+ */
+class YamlReader extends RefType {
+ YamlReader() { this.hasQualifiedName("com.esotericsoftware.yamlbeans", "YamlReader") }
+}
+
+/** A method with the name `read` declared in `com.esotericsoftware.yamlbeans.YamlReader`. */
+class YamlReaderReadMethod extends Method {
+ YamlReaderReadMethod() {
+ this.getDeclaringType() instanceof YamlReader and
+ this.getName() = "read"
+ }
+}
diff --git a/java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll b/java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll
index ab809f07d6d..377303601d4 100644
--- a/java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll
+++ b/java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll
@@ -2,6 +2,11 @@ import semmle.code.java.frameworks.Kryo
import semmle.code.java.frameworks.XStream
import semmle.code.java.frameworks.SnakeYaml
import semmle.code.java.frameworks.FastJson
+import semmle.code.java.frameworks.JYaml
+import semmle.code.java.frameworks.JsonIo
+import semmle.code.java.frameworks.YamlBeans
+import semmle.code.java.frameworks.Hessian
+import semmle.code.java.frameworks.Castor
import semmle.code.java.frameworks.apache.Lang
class ObjectInputStreamReadObjectMethod extends Method {
@@ -50,6 +55,29 @@ class SafeKryo extends DataFlow2::Configuration {
}
}
+class SafeJsonIo extends DataFlow2::Configuration {
+ SafeJsonIo() { this = "UnsafeDeserialization::SafeJsonIo" }
+
+ override predicate isSource(DataFlow::Node src) {
+ exists(MethodAccess ma |
+ ma instanceof JsonIoSafeOptionalArgs and
+ src.asExpr() = ma.getQualifier()
+ )
+ }
+
+ override predicate isSink(DataFlow::Node sink) {
+ exists(MethodAccess ma |
+ ma.getMethod() instanceof JsonIoJsonToJavaMethod and
+ sink.asExpr() = ma.getArgument(1)
+ )
+ or
+ exists(ClassInstanceExpr cie |
+ cie.getConstructor().getDeclaringType() instanceof JsonReader and
+ sink.asExpr() = cie.getArgument(1)
+ )
+ }
+}
+
predicate unsafeDeserialization(MethodAccess ma, Expr sink) {
exists(Method m | m = ma.getMethod() |
m instanceof ObjectInputStreamReadObjectMethod and
@@ -81,6 +109,27 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) {
ma.getMethod() instanceof FastJsonParseMethod and
not fastJsonLooksSafe() and
sink = ma.getArgument(0)
+ or
+ ma.getMethod() instanceof JYamlUnSafeLoadMethod and
+ sink = ma.getArgument(0)
+ or
+ ma.getMethod() instanceof JYamlConfigUnSafeLoadMethod and
+ sink = ma.getArgument(0)
+ or
+ ma.getMethod() instanceof JsonIoJsonToJavaMethod and
+ sink = ma.getArgument(0) and
+ not exists(SafeJsonIo sji | sji.hasFlowToExpr(ma.getArgument(1)))
+ or
+ ma.getMethod() instanceof JsonIoReadObjectMethod and
+ sink = ma.getQualifier()
+ or
+ ma.getMethod() instanceof YamlReaderReadMethod and sink = ma.getQualifier()
+ or
+ ma.getMethod() instanceof UnSafeHessianInputReadObjectMethod and sink = ma.getQualifier()
+ or
+ ma.getMethod() instanceof UnmarshalMethod and sink = ma.getAnArgument()
+ or
+ ma.getMethod() instanceof BurlapInputReadObjectMethod and sink = ma.getQualifier()
)
}
diff --git a/java/ql/test/query-tests/security/CWE-502/C.java b/java/ql/test/query-tests/security/CWE-502/C.java
new file mode 100644
index 00000000000..ede36d8410b
--- /dev/null
+++ b/java/ql/test/query-tests/security/CWE-502/C.java
@@ -0,0 +1,98 @@
+import java.util.HashMap;
+import java.io.StringReader;
+import javax.servlet.http.HttpServletRequest;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import com.cedarsoftware.util.io.JsonReader;
+import com.esotericsoftware.yamlbeans.YamlReader;
+import org.ho.yaml.Yaml;
+import org.ho.yaml.YamlConfig;
+import org.exolab.castor.xml.Unmarshaller;
+import com.caucho.hessian.io.Hessian2Input;
+import com.caucho.hessian.io.HessianInput;
+import com.caucho.burlap.io.BurlapInput;
+import com.caucho.hessian.io.Hessian2Input;
+import com.caucho.hessian.io.HessianInput;
+import java.io.ByteArrayInputStream;
+
+@Controller
+public class C {
+
+ @GetMapping(value = "jyaml")
+ public void bad1(HttpServletRequest request) throws Exception {
+ String data = request.getParameter("data");
+ Yaml.load(data); //bad
+ Yaml.loadStream(data); //bad
+ Yaml.loadStreamOfType(data, Object.class); //bad
+ Yaml.loadType(data, Object.class); //bad
+
+ org.ho.yaml.YamlConfig yamlConfig = new YamlConfig();
+ yamlConfig.load(data); //bad
+ yamlConfig.loadStream(data); //bad
+ yamlConfig.loadStreamOfType(data, Object.class); //bad
+ yamlConfig.loadType(data, Object.class); //bad
+ }
+
+ @GetMapping(value = "jsonio")
+ public void bad2(HttpServletRequest request) {
+ String data = request.getParameter("data");
+
+ HashMap hashMap = new HashMap();
+ hashMap.put("USE_MAPS", true);
+
+ JsonReader.jsonToJava(data); //bad
+
+ JsonReader.jsonToJava(data, hashMap); //good
+
+ JsonReader jr = new JsonReader(data, null); //bad
+ jr.readObject();
+
+ JsonReader jr1 = new JsonReader(data, hashMap); //good
+ jr1.readObject();
+ }
+
+ @GetMapping(value = "yamlbeans")
+ public void bad3(HttpServletRequest request) throws Exception {
+ String data = request.getParameter("data");
+ YamlReader r = new YamlReader(data);
+ r.read(); //bad
+ r.read(Object.class); //bad
+ r.read(Object.class, Object.class); //bad
+ }
+
+ @GetMapping(value = "hessian")
+ public void bad4(HttpServletRequest request) throws Exception {
+ byte[] bytes = request.getParameter("data").getBytes();
+ ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
+ HessianInput hessianInput = new HessianInput(bis);
+ hessianInput.readObject(); //bad
+ hessianInput.readObject(Object.class); //bad
+ }
+
+ @GetMapping(value = "hessian2")
+ public void bad5(HttpServletRequest request) throws Exception {
+ byte[] bytes = request.getParameter("data").getBytes();
+ ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
+ Hessian2Input hessianInput = new Hessian2Input(bis);
+ hessianInput.readObject(); //bad
+ hessianInput.readObject(Object.class); //bad
+ }
+
+ @GetMapping(value = "castor")
+ public void bad6(HttpServletRequest request) throws Exception {
+ Unmarshaller unmarshaller = new Unmarshaller();
+ unmarshaller.unmarshal(new StringReader(request.getParameter("data"))); //bad
+ }
+
+ @GetMapping(value = "burlap")
+ public void bad7(HttpServletRequest request) throws Exception {
+ byte[] serializedData = request.getParameter("data").getBytes();
+ ByteArrayInputStream is = new ByteArrayInputStream(serializedData);
+ BurlapInput burlapInput = new BurlapInput(is);
+ burlapInput.readObject(); //bad
+
+ BurlapInput burlapInput1 = new BurlapInput();
+ burlapInput1.init(is);
+ burlapInput1.readObject(); //bad
+ }
+}
diff --git a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected
index f575a093d6e..d583caafc9b 100644
--- a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected
+++ b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected
@@ -25,6 +25,26 @@ edges
| B.java:12:31:12:51 | getInputStream(...) : InputStream | B.java:15:23:15:27 | bytes |
| B.java:19:31:19:51 | getInputStream(...) : InputStream | B.java:23:29:23:29 | s |
| B.java:27:31:27:51 | getInputStream(...) : InputStream | B.java:31:23:31:23 | s |
+| C.java:23:17:23:44 | getParameter(...) : String | C.java:24:13:24:16 | data |
+| C.java:23:17:23:44 | getParameter(...) : String | C.java:25:19:25:22 | data |
+| C.java:23:17:23:44 | getParameter(...) : String | C.java:26:25:26:28 | data |
+| C.java:23:17:23:44 | getParameter(...) : String | C.java:27:17:27:20 | data |
+| C.java:23:17:23:44 | getParameter(...) : String | C.java:30:19:30:22 | data |
+| C.java:23:17:23:44 | getParameter(...) : String | C.java:31:25:31:28 | data |
+| C.java:23:17:23:44 | getParameter(...) : String | C.java:32:31:32:34 | data |
+| C.java:23:17:23:44 | getParameter(...) : String | C.java:33:23:33:26 | data |
+| C.java:38:17:38:44 | getParameter(...) : String | C.java:43:25:43:28 | data |
+| C.java:38:17:38:44 | getParameter(...) : String | C.java:48:3:48:4 | jr |
+| C.java:56:17:56:44 | getParameter(...) : String | C.java:58:3:58:3 | r |
+| C.java:56:17:56:44 | getParameter(...) : String | C.java:59:3:59:3 | r |
+| C.java:56:17:56:44 | getParameter(...) : String | C.java:60:3:60:3 | r |
+| C.java:65:18:65:45 | getParameter(...) : String | C.java:68:3:68:14 | hessianInput |
+| C.java:65:18:65:45 | getParameter(...) : String | C.java:69:3:69:14 | hessianInput |
+| C.java:74:18:74:45 | getParameter(...) : String | C.java:77:3:77:14 | hessianInput |
+| C.java:74:18:74:45 | getParameter(...) : String | C.java:78:3:78:14 | hessianInput |
+| C.java:84:43:84:70 | getParameter(...) : String | C.java:84:26:84:71 | new StringReader(...) |
+| C.java:89:27:89:54 | getParameter(...) : String | C.java:92:3:92:13 | burlapInput |
+| C.java:89:27:89:54 | getParameter(...) : String | C.java:96:3:96:14 | burlapInput1 |
| TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) |
nodes
| A.java:13:31:13:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
@@ -65,6 +85,33 @@ nodes
| B.java:23:29:23:29 | s | semmle.label | s |
| B.java:27:31:27:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| B.java:31:23:31:23 | s | semmle.label | s |
+| C.java:23:17:23:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
+| C.java:24:13:24:16 | data | semmle.label | data |
+| C.java:25:19:25:22 | data | semmle.label | data |
+| C.java:26:25:26:28 | data | semmle.label | data |
+| C.java:27:17:27:20 | data | semmle.label | data |
+| C.java:30:19:30:22 | data | semmle.label | data |
+| C.java:31:25:31:28 | data | semmle.label | data |
+| C.java:32:31:32:34 | data | semmle.label | data |
+| C.java:33:23:33:26 | data | semmle.label | data |
+| C.java:38:17:38:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
+| C.java:43:25:43:28 | data | semmle.label | data |
+| C.java:48:3:48:4 | jr | semmle.label | jr |
+| C.java:56:17:56:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
+| C.java:58:3:58:3 | r | semmle.label | r |
+| C.java:59:3:59:3 | r | semmle.label | r |
+| C.java:60:3:60:3 | r | semmle.label | r |
+| C.java:65:18:65:45 | getParameter(...) : String | semmle.label | getParameter(...) : String |
+| C.java:68:3:68:14 | hessianInput | semmle.label | hessianInput |
+| C.java:69:3:69:14 | hessianInput | semmle.label | hessianInput |
+| C.java:74:18:74:45 | getParameter(...) : String | semmle.label | getParameter(...) : String |
+| C.java:77:3:77:14 | hessianInput | semmle.label | hessianInput |
+| C.java:78:3:78:14 | hessianInput | semmle.label | hessianInput |
+| C.java:84:26:84:71 | new StringReader(...) | semmle.label | new StringReader(...) |
+| C.java:84:43:84:70 | getParameter(...) : String | semmle.label | getParameter(...) : String |
+| C.java:89:27:89:54 | getParameter(...) : String | semmle.label | getParameter(...) : String |
+| C.java:92:3:92:13 | burlapInput | semmle.label | burlapInput |
+| C.java:96:3:96:14 | burlapInput1 | semmle.label | burlapInput1 |
| TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | semmle.label | entityStream : InputStream |
| TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) | semmle.label | new ObjectInputStream(...) |
#select
@@ -94,4 +141,24 @@ nodes
| B.java:15:12:15:28 | parse(...) | B.java:12:31:12:51 | getInputStream(...) : InputStream | B.java:15:23:15:27 | bytes | Unsafe deserialization of $@. | B.java:12:31:12:51 | getInputStream(...) | user input |
| B.java:23:12:23:30 | parseObject(...) | B.java:19:31:19:51 | getInputStream(...) : InputStream | B.java:23:29:23:29 | s | Unsafe deserialization of $@. | B.java:19:31:19:51 | getInputStream(...) | user input |
| B.java:31:12:31:24 | parse(...) | B.java:27:31:27:51 | getInputStream(...) : InputStream | B.java:31:23:31:23 | s | Unsafe deserialization of $@. | B.java:27:31:27:51 | getInputStream(...) | user input |
+| C.java:24:3:24:17 | load(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:24:13:24:16 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
+| C.java:25:3:25:23 | loadStream(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:25:19:25:22 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
+| C.java:26:3:26:43 | loadStreamOfType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:26:25:26:28 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
+| C.java:27:3:27:35 | loadType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:27:17:27:20 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
+| C.java:30:3:30:23 | load(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:30:19:30:22 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
+| C.java:31:3:31:29 | loadStream(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:31:25:31:28 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
+| C.java:32:3:32:49 | loadStreamOfType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:32:31:32:34 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
+| C.java:33:3:33:41 | loadType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:33:23:33:26 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
+| C.java:43:3:43:29 | jsonToJava(...) | C.java:38:17:38:44 | getParameter(...) : String | C.java:43:25:43:28 | data | Unsafe deserialization of $@. | C.java:38:17:38:44 | getParameter(...) | user input |
+| C.java:48:3:48:17 | readObject(...) | C.java:38:17:38:44 | getParameter(...) : String | C.java:48:3:48:4 | jr | Unsafe deserialization of $@. | C.java:38:17:38:44 | getParameter(...) | user input |
+| C.java:58:3:58:10 | read(...) | C.java:56:17:56:44 | getParameter(...) : String | C.java:58:3:58:3 | r | Unsafe deserialization of $@. | C.java:56:17:56:44 | getParameter(...) | user input |
+| C.java:59:3:59:22 | read(...) | C.java:56:17:56:44 | getParameter(...) : String | C.java:59:3:59:3 | r | Unsafe deserialization of $@. | C.java:56:17:56:44 | getParameter(...) | user input |
+| C.java:60:3:60:36 | read(...) | C.java:56:17:56:44 | getParameter(...) : String | C.java:60:3:60:3 | r | Unsafe deserialization of $@. | C.java:56:17:56:44 | getParameter(...) | user input |
+| C.java:68:3:68:27 | readObject(...) | C.java:65:18:65:45 | getParameter(...) : String | C.java:68:3:68:14 | hessianInput | Unsafe deserialization of $@. | C.java:65:18:65:45 | getParameter(...) | user input |
+| C.java:69:3:69:39 | readObject(...) | C.java:65:18:65:45 | getParameter(...) : String | C.java:69:3:69:14 | hessianInput | Unsafe deserialization of $@. | C.java:65:18:65:45 | getParameter(...) | user input |
+| C.java:77:3:77:27 | readObject(...) | C.java:74:18:74:45 | getParameter(...) : String | C.java:77:3:77:14 | hessianInput | Unsafe deserialization of $@. | C.java:74:18:74:45 | getParameter(...) | user input |
+| C.java:78:3:78:39 | readObject(...) | C.java:74:18:74:45 | getParameter(...) : String | C.java:78:3:78:14 | hessianInput | Unsafe deserialization of $@. | C.java:74:18:74:45 | getParameter(...) | user input |
+| C.java:84:3:84:72 | unmarshal(...) | C.java:84:43:84:70 | getParameter(...) : String | C.java:84:26:84:71 | new StringReader(...) | Unsafe deserialization of $@. | C.java:84:43:84:70 | getParameter(...) | user input |
+| C.java:92:3:92:26 | readObject(...) | C.java:89:27:89:54 | getParameter(...) : String | C.java:92:3:92:13 | burlapInput | Unsafe deserialization of $@. | C.java:89:27:89:54 | getParameter(...) | user input |
+| C.java:96:3:96:27 | readObject(...) | C.java:89:27:89:54 | getParameter(...) : String | C.java:96:3:96:14 | burlapInput1 | Unsafe deserialization of $@. | C.java:89:27:89:54 | getParameter(...) | user input |
| TestMessageBodyReader.java:22:18:22:65 | readObject(...) | TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) | Unsafe deserialization of $@. | TestMessageBodyReader.java:20:55:20:78 | entityStream | user input |
diff --git a/java/ql/test/query-tests/security/CWE-502/options b/java/ql/test/query-tests/security/CWE-502/options
index 6df0c9374c2..ebf1581cc8a 100644
--- a/java/ql/test/query-tests/security/CWE-502/options
+++ b/java/ql/test/query-tests/security/CWE-502/options
@@ -1 +1 @@
-//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74
+//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1
diff --git a/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/types/AnyNode.java b/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/types/AnyNode.java
new file mode 100644
index 00000000000..f29270d2521
--- /dev/null
+++ b/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/types/AnyNode.java
@@ -0,0 +1,11 @@
+package org.exolab.castor.types;
+
+import java.io.Serializable;
+
+public final class AnyNode implements Serializable {
+
+ private static final long serialVersionUID = -4104117996051705975L;
+
+ public AnyNode() { }
+}
+
diff --git a/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/EventProducer.java b/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/EventProducer.java
new file mode 100644
index 00000000000..08893c95a48
--- /dev/null
+++ b/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/EventProducer.java
@@ -0,0 +1,12 @@
+package org.exolab.castor.xml;
+
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.SAXException;
+
+/** @deprecated */
+public interface EventProducer {
+ void setDocumentHandler(DocumentHandler var1);
+
+ void start() throws SAXException;
+}
+
diff --git a/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/SAX2EventAndErrorProducer.java b/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/SAX2EventAndErrorProducer.java
new file mode 100644
index 00000000000..77978b53f01
--- /dev/null
+++ b/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/SAX2EventAndErrorProducer.java
@@ -0,0 +1,8 @@
+package org.exolab.castor.xml;
+
+import org.xml.sax.ErrorHandler;
+
+public interface SAX2EventAndErrorProducer extends SAX2EventProducer {
+ void setErrorHandler(ErrorHandler var1);
+}
+
diff --git a/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/SAX2EventProducer.java b/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/SAX2EventProducer.java
new file mode 100644
index 00000000000..66b2cf8259f
--- /dev/null
+++ b/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/SAX2EventProducer.java
@@ -0,0 +1,11 @@
+package org.exolab.castor.xml;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+public interface SAX2EventProducer {
+ void setContentHandler(ContentHandler var1);
+
+ void start() throws SAXException;
+}
+
diff --git a/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/Unmarshaller.java b/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/Unmarshaller.java
new file mode 100644
index 00000000000..cc76c2c5e6a
--- /dev/null
+++ b/java/ql/test/stubs/castor-1.4.1/org/exolab/castor/xml/Unmarshaller.java
@@ -0,0 +1,74 @@
+package org.exolab.castor.xml;
+
+import java.io.Reader;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.Source;
+import org.exolab.castor.types.AnyNode;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+public class Unmarshaller {
+
+ public Unmarshaller() { }
+
+ public Object unmarshal(Reader reader) {
+ return null;
+ }
+
+ public Object unmarshal(EventProducer eventProducer) {
+ return null;
+ }
+
+ public Object unmarshal(SAX2EventProducer eventProducer) {
+ return null;
+ }
+
+ public Object unmarshal(AnyNode anyNode) {
+ return null;
+ }
+
+ public Object unmarshal(InputSource source) {
+ return null;
+ }
+
+ public Object unmarshal(Node node) {
+ return null;
+ }
+
+ public Object unmarshal(XMLEventReader eventReader) {
+ return null;
+ }
+
+ public Object unmarshal(XMLStreamReader streamReader) {
+ return null;
+ }
+
+ public Object unmarshal(SAX2EventAndErrorProducer eventProducer) {
+ return null;
+ }
+
+ public Object unmarshal(Source source) {
+ return null;
+ }
+
+ public static Object unmarshal(Class c, Reader reader) {
+ return null;
+ }
+
+ private static Unmarshaller createUnmarshaller(Class clazz) {
+ return null;
+ }
+
+ public static Object unmarshal(Class c, InputSource source) {
+ return null;
+ }
+
+ public static Object unmarshal(Class c, Node node) {
+ return null;
+ }
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/AbstractBurlapInput.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/AbstractBurlapInput.java
new file mode 100644
index 00000000000..9bf1892ea5b
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/AbstractBurlapInput.java
@@ -0,0 +1,9 @@
+package com.caucho.burlap.io;
+
+import com.caucho.hessian.io.AbstractHessianInput;
+
+public abstract class AbstractBurlapInput extends AbstractHessianInput {
+ public AbstractBurlapInput() {
+ }
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/AbstractHessianInput.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/AbstractHessianInput.java
new file mode 100644
index 00000000000..aff9f533850
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/AbstractHessianInput.java
@@ -0,0 +1,110 @@
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import org.w3c.dom.Node;
+
+public abstract class AbstractHessianInput {
+
+ public AbstractHessianInput() {
+ }
+
+ public void init(InputStream is) {
+ }
+
+ public abstract String getMethod();
+
+ public void setSerializerFactory(SerializerFactory ser) {
+ }
+
+ public abstract int readCall() throws IOException;
+
+ public void skipOptionalCall() throws IOException {
+ }
+
+ public abstract String readHeader() throws IOException;
+
+ public abstract String readMethod() throws IOException;
+
+ public int readMethodArgLength() throws IOException {
+ return -1;
+ }
+
+ public abstract void startCall() throws IOException;
+
+ public abstract void completeCall() throws IOException;
+
+ public abstract Object readReply(Class var1) throws Throwable;
+
+ public abstract void startReply() throws Throwable;
+
+ public void startReplyBody() throws Throwable {
+ }
+
+ public abstract void completeReply() throws IOException;
+
+ public abstract boolean readBoolean() throws IOException;
+
+ public abstract void readNull() throws IOException;
+
+ public abstract int readInt() throws IOException;
+
+ public abstract long readLong() throws IOException;
+
+ public abstract double readDouble() throws IOException;
+
+ public abstract long readUTCDate() throws IOException;
+
+ public abstract String readString() throws IOException;
+
+ public Node readNode() throws IOException {
+ return null;
+ }
+
+ public abstract Reader getReader() throws IOException;
+
+ public abstract InputStream readInputStream() throws IOException;
+
+ public boolean readToOutputStream(OutputStream os) throws IOException {
+ return true;
+ }
+
+ public abstract byte[] readBytes() throws IOException;
+
+ public abstract Object readObject(Class var1) throws IOException;
+
+ public abstract Object readObject() throws IOException;
+
+ public abstract Object readRemote() throws IOException;
+
+ public abstract Object readRef() throws IOException;
+
+ public abstract int addRef(Object var1) throws IOException;
+
+ public abstract void setRef(int var1, Object var2) throws IOException;
+
+ public void resetReferences() {
+ }
+
+ public abstract int readListStart() throws IOException;
+
+ public abstract int readLength() throws IOException;
+
+ public abstract int readMapStart() throws IOException;
+
+ public abstract String readType() throws IOException;
+
+ public abstract boolean isEnd() throws IOException;
+
+ public abstract void readEnd() throws IOException;
+
+ public abstract void readMapEnd() throws IOException;
+
+ public abstract void readListEnd() throws IOException;
+
+ public void close() throws IOException {
+ }
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/AbstractSerializerFactory.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/AbstractSerializerFactory.java
new file mode 100644
index 00000000000..d4bc523ec87
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/AbstractSerializerFactory.java
@@ -0,0 +1,11 @@
+package com.caucho.hessian.io;
+
+public abstract class AbstractSerializerFactory {
+ public AbstractSerializerFactory() {
+ }
+
+ public abstract Serializer getSerializer(Class var1) throws HessianProtocolException;
+
+ public abstract Deserializer getDeserializer(Class var1) throws HessianProtocolException;
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/BurlapInput.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/BurlapInput.java
new file mode 100644
index 00000000000..ec02d2f302b
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/BurlapInput.java
@@ -0,0 +1,274 @@
+package com.caucho.burlap.io;
+
+import com.caucho.hessian.io.SerializerFactory;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.TimeZone;
+import org.w3c.dom.Node;
+
+public class BurlapInput extends AbstractBurlapInput {
+
+ public BurlapInput() { }
+
+ public BurlapInput(InputStream is) { }
+
+ public void setSerializerFactory(SerializerFactory factory) { }
+
+ public SerializerFactory getSerializerFactory() {
+ return null;
+ }
+
+ public void init(InputStream is) { }
+
+ public String getMethod() {
+ return null;
+ }
+
+ public Throwable getReplyFault() {
+ return null;
+ }
+
+ public void startCall() throws IOException { }
+
+ public int readCall() throws IOException {
+ return 1;
+ }
+
+ public String readMethod() throws IOException {
+ return null;
+ }
+
+ public void completeCall() throws IOException { }
+
+ public Object readReply(Class expectedClass) throws Throwable {
+ return null;
+ }
+
+ public void startReply() throws Throwable { }
+
+ private Throwable prepareFault() throws IOException {
+ return null;
+ }
+
+ public void completeReply() throws IOException { }
+
+ public String readHeader() throws IOException {
+ return null;
+ }
+
+ public void readNull() throws IOException { }
+
+ public boolean readBoolean() throws IOException {
+ return true;
+ }
+
+ public byte readByte() throws IOException {
+ return 1;
+ }
+
+ public short readShort() throws IOException {
+ return 1;
+ }
+
+ public int readInt() throws IOException {
+ return 1;
+ }
+
+ public long readLong() throws IOException {
+ return 1L;
+ }
+
+ public float readFloat() throws IOException {
+ return 1.1F;
+ }
+
+ public double readDouble() throws IOException {
+ return 1.1;
+ }
+
+ public long readUTCDate() throws IOException {
+ return 1L;
+ }
+
+ public long readLocalDate() throws IOException {
+ return 1L;
+ }
+
+ public String readString() throws IOException {
+ return null;
+ }
+
+ public Node readNode() throws IOException {
+ return null;
+ }
+
+ public byte[] readBytes() throws IOException {
+ return null;
+ }
+
+ public int readLength() throws IOException {
+ return 1;
+ }
+
+ private HashMap readFault() throws IOException {
+ return null;
+ }
+
+ public Object readObject(Class cl) throws IOException {
+ return null;
+ }
+
+ public Object readObject() throws IOException {
+ return null;
+ }
+
+ public Object readRemote() throws IOException {
+ return null;
+ }
+
+ public Object readRef() throws IOException {
+ return null;
+ }
+
+ public int readListStart() throws IOException {
+ return 1;
+ }
+
+ public int readMapStart() throws IOException {
+ return 1;
+ }
+
+ public boolean isEnd() throws IOException {
+ return true;
+ }
+
+ public void readEnd() throws IOException { }
+
+ public void readMapEnd() throws IOException { }
+
+ public void readListEnd() throws IOException { }
+
+ public int addRef(Object ref) {
+ return 1;
+ }
+
+ public void setRef(int i, Object ref) { }
+
+ public Object resolveRemote(String type, String url) throws IOException {
+ return null;
+ }
+
+ public String readType() throws IOException {
+ return null;
+ }
+
+ private int parseInt() throws IOException {
+ return 1;
+ }
+
+ private long parseLong() throws IOException {
+ return 1L;
+ }
+
+ private double parseDouble() throws IOException {
+ return 1.1;
+ }
+
+ protected long parseDate() throws IOException {
+ return 1L;
+ }
+
+ protected long parseDate(Calendar calendar) throws IOException {
+ return 1L;
+ }
+
+ protected String parseString() throws IOException {
+ return null;
+ }
+
+ protected StringBuffer parseString(StringBuffer sbuf) throws IOException {
+ return null;
+ }
+
+ Node parseXML() throws IOException {
+ return null;
+ }
+
+ int readChar() throws IOException {
+ return 1;
+ }
+
+ protected byte[] parseBytes() throws IOException {
+ return null;
+ }
+
+ protected ByteArrayOutputStream parseBytes(ByteArrayOutputStream bos) throws IOException {
+ return null;
+ }
+
+ public void expectTag(int expectTag) throws IOException { }
+
+ protected int parseTag() throws IOException {
+ return 1;
+ }
+
+ private boolean isTagChar(int ch) {
+ return true;
+ }
+
+ protected int skipWhitespace() throws IOException {
+ return 1;
+ }
+
+ protected boolean isWhitespace(int ch) throws IOException {
+ return true;
+ }
+
+ int read(byte[] buffer, int offset, int length) throws IOException {
+ return 1;
+ }
+
+ int read() throws IOException {
+ return 1;
+ }
+
+ public Reader getReader() {
+ return null;
+ }
+
+ public InputStream readInputStream() {
+ return null;
+ }
+
+ public InputStream getInputStream() {
+ return null;
+ }
+
+ protected IOException expectBeginTag(String expect, String tag) {
+ return null;
+ }
+
+ protected IOException expectedChar(String expect, int ch) {
+ return null;
+ }
+
+ protected IOException expectedTag(String expect, int tag) {
+ return null;
+ }
+
+ protected IOException error(String message) {
+ return null;
+ }
+
+ protected static String tagName(int tag) {
+ return null;
+ }
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/Deserializer.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/Deserializer.java
new file mode 100644
index 00000000000..2a96e53c397
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/Deserializer.java
@@ -0,0 +1,26 @@
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+public interface Deserializer {
+ Class> getType();
+
+ boolean isReadResolve();
+
+ Object readObject(AbstractHessianInput var1) throws IOException;
+
+ Object readList(AbstractHessianInput var1, int var2) throws IOException;
+
+ Object readLengthList(AbstractHessianInput var1, int var2) throws IOException;
+
+ Object readMap(AbstractHessianInput var1) throws IOException;
+
+ Object[] createFields(int var1);
+
+ Object createField(String var1);
+
+ Object readObject(AbstractHessianInput var1, Object[] var2) throws IOException;
+
+ Object readObject(AbstractHessianInput var1, String[] var2) throws IOException;
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/HessianProtocolException.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/HessianProtocolException.java
new file mode 100644
index 00000000000..173d5876c03
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/HessianProtocolException.java
@@ -0,0 +1,24 @@
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+public class HessianProtocolException extends IOException {
+
+ public HessianProtocolException() {
+ }
+
+ public HessianProtocolException(String message) { }
+
+ public HessianProtocolException(String message, Throwable rootCause) { }
+
+ public HessianProtocolException(Throwable rootCause) { }
+
+ public Throwable getRootCause() {
+ return null;
+ }
+
+ public Throwable getCause() {
+ return null;
+ }
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/Serializer.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/Serializer.java
new file mode 100644
index 00000000000..fbd3f5bc9c8
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/Serializer.java
@@ -0,0 +1,8 @@
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+public interface Serializer {
+
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/SerializerFactory.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/SerializerFactory.java
new file mode 100644
index 00000000000..96716eca3ae
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/burlap/io/SerializerFactory.java
@@ -0,0 +1,12 @@
+package com.caucho.hessian.io;
+
+public class SerializerFactory extends AbstractSerializerFactory {
+
+ public Serializer getSerializer(Class cl) throws HessianProtocolException {
+ return null;
+ }
+
+ public Deserializer getDeserializer(Class cl) throws HessianProtocolException {
+ return null;
+ }
+}
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/AbstractHessianInput.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/AbstractHessianInput.java
new file mode 100644
index 00000000000..4b9d3b7ad44
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/AbstractHessianInput.java
@@ -0,0 +1,111 @@
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+
+public abstract class AbstractHessianInput {
+
+ public AbstractHessianInput() {
+ }
+
+ public void init(InputStream is) {
+ }
+
+ public abstract String getMethod();
+
+ public void setRemoteResolver(HessianRemoteResolver resolver) { }
+
+ public HessianRemoteResolver getRemoteResolver() {
+ return null;
+ }
+
+ public void setSerializerFactory(SerializerFactory ser) {
+ }
+
+ public abstract int readCall() throws IOException;
+
+ public void skipOptionalCall() throws IOException {
+ }
+
+ public abstract String readHeader() throws IOException;
+
+ public abstract String readMethod() throws IOException;
+
+ public int readMethodArgLength() throws IOException {
+ return -1;
+ }
+
+ public abstract void startCall() throws IOException;
+
+ public abstract void completeCall() throws IOException;
+
+ public abstract Object readReply(Class var1) throws Throwable;
+
+ public abstract void startReply() throws Throwable;
+
+ public void startReplyBody() throws Throwable {
+ }
+
+ public abstract void completeReply() throws IOException;
+
+ public abstract boolean readBoolean() throws IOException;
+
+ public abstract void readNull() throws IOException;
+
+ public abstract int readInt() throws IOException;
+
+ public abstract long readLong() throws IOException;
+
+ public abstract double readDouble() throws IOException;
+
+ public abstract long readUTCDate() throws IOException;
+
+ public abstract String readString() throws IOException;
+
+ public abstract Reader getReader() throws IOException;
+
+ public abstract InputStream readInputStream() throws IOException;
+
+ public boolean readToOutputStream(OutputStream os) throws IOException {
+ return true;
+ }
+
+ public abstract byte[] readBytes() throws IOException;
+
+ public abstract Object readObject(Class var1) throws IOException;
+
+ public abstract Object readObject() throws IOException;
+
+ public abstract Object readRemote() throws IOException;
+
+ public abstract Object readRef() throws IOException;
+
+ public abstract int addRef(Object var1) throws IOException;
+
+ public abstract void setRef(int var1, Object var2) throws IOException;
+
+ public void resetReferences() {
+ }
+
+ public abstract int readListStart() throws IOException;
+
+ public abstract int readLength() throws IOException;
+
+ public abstract int readMapStart() throws IOException;
+
+ public abstract String readType() throws IOException;
+
+ public abstract boolean isEnd() throws IOException;
+
+ public abstract void readEnd() throws IOException;
+
+ public abstract void readMapEnd() throws IOException;
+
+ public abstract void readListEnd() throws IOException;
+
+ public void close() throws IOException {
+ }
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/Hessian2Input.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/Hessian2Input.java
new file mode 100644
index 00000000000..1ed011945e1
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/Hessian2Input.java
@@ -0,0 +1,297 @@
+package com.caucho.hessian.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class Hessian2Input extends AbstractHessianInput {
+
+ public Hessian2Input() { }
+
+ public Hessian2Input(InputStream is) { }
+
+ public String getMethod() {
+ return null;
+ }
+
+ public Throwable getReplyFault() {
+ return null;
+ }
+
+ public int readCall() throws IOException {
+ return 1;
+ }
+
+ public int readEnvelope() throws IOException {
+ return 1;
+ }
+
+ public void completeEnvelope() throws IOException { }
+
+ public String readMethod() throws IOException {
+ return null;
+ }
+
+ public int readMethodArgLength() throws IOException {
+ return 1;
+ }
+
+ public void startCall() throws IOException { }
+
+ public Object[] readArguments() throws IOException {
+ return null;
+ }
+
+ public void completeCall() throws IOException { }
+
+ public Object readReply(Class expectedClass) throws Throwable {
+ return null;
+ }
+
+ public void startReply() throws Throwable { }
+
+ private Throwable prepareFault(HashMap fault) throws IOException {
+ return null;
+ }
+
+ public void completeReply() throws IOException { }
+
+ public void completeValueReply() throws IOException { }
+
+ public String readHeader() throws IOException {
+ return null;
+ }
+
+ public int startMessage() throws IOException {
+ return 1;
+ }
+
+ public void completeMessage() throws IOException { }
+
+ public void readNull() throws IOException { }
+
+ public boolean readBoolean() throws IOException {
+ return true;
+ }
+
+ public short readShort() throws IOException {
+ return 11111;
+ }
+
+ public final int readInt() throws IOException {
+ return 1;
+ }
+
+ public long readLong() throws IOException {
+ return 1L;
+ }
+
+ public float readFloat() throws IOException {
+ return 1.1F;
+ }
+
+ public double readDouble() throws IOException {
+ return 1.1;
+ }
+
+ public long readUTCDate() throws IOException {
+ return 1L;
+ }
+
+ public int readChar() throws IOException {
+ return 1;
+ }
+
+ public int readString(char[] buffer, int offset, int length) throws IOException {
+ return 1;
+ }
+
+ public String readString() throws IOException {
+ return null;
+ }
+
+ public byte[] readBytes() throws IOException {
+ return null;
+ }
+
+ public int readByte() throws IOException {
+ return 1;
+ }
+
+ public int readBytes(byte[] buffer, int offset, int length) throws IOException {
+ return 1;
+ }
+
+ private HashMap readFault() throws IOException {
+ return null;
+ }
+
+ public Object readObject(Class cl) throws IOException {
+ return null;
+ }
+
+ public Object readObject() throws IOException {
+ return null;
+ }
+
+ private void readObjectDefinition(Class> cl) throws IOException { }
+
+ private Object readObjectInstance(Class> cl, Hessian2Input.ObjectDefinition def) throws IOException {
+ return null;
+ }
+
+ public Object readRemote() throws IOException {
+ return null;
+ }
+
+ public Object readRef() throws IOException {
+ return null;
+ }
+
+ public int readListStart() throws IOException {
+ return 1;
+ }
+
+ public int readMapStart() throws IOException {
+ return 1;
+ }
+
+ public boolean isEnd() throws IOException {
+ return true;
+ }
+
+ public void readEnd() throws IOException { }
+
+ public void readMapEnd() throws IOException { }
+
+ public void readListEnd() throws IOException { }
+
+ public int addRef(Object ref) {
+ return 1;
+ }
+
+ public void setRef(int i, Object ref) { }
+
+ public void resetReferences() { }
+
+ public void reset() { }
+
+ public void resetBuffer() { }
+
+ public Object readStreamingObject() throws IOException {
+ return null;
+ }
+
+ public Object resolveRemote(String type, String url) throws IOException {
+ return null;
+ }
+
+ public String readType() throws IOException {
+ return null;
+ }
+
+ public int readLength() throws IOException {
+ return 1;
+ }
+
+ private int parseInt() throws IOException {
+ return 1;
+ }
+
+ private long parseLong() throws IOException {
+ return 1L;
+ }
+
+ private double parseDouble() throws IOException {
+ return 1.1;
+ }
+
+ private void parseString(StringBuilder sbuf) throws IOException { }
+
+ private int parseChar() throws IOException {
+ return 1;
+ }
+
+ private boolean parseChunkLength() throws IOException {
+ return true;
+ }
+
+ private int parseUTF8Char() throws IOException {
+ return 1;
+ }
+
+ private int parseByte() throws IOException {
+ return 1;
+ }
+
+ public InputStream readInputStream() throws IOException {
+ return null;
+ }
+
+ int read(byte[] buffer, int offset, int length) throws IOException {
+ return 1;
+ }
+
+ public final int read() throws IOException {
+ return 1;
+ }
+
+ protected void unread() { }
+
+ private final boolean readBuffer() throws IOException {
+ return true;
+ }
+
+ public Reader getReader() {
+ return null;
+ }
+
+ protected IOException expect(String expect, int ch) throws IOException {
+ return null;
+ }
+
+ private String buildDebugContext(byte[] buffer, int offset, int length, int errorOffset) {
+ return null;
+ }
+
+ private void addDebugChar(StringBuilder sb, int ch) { }
+
+ protected String codeName(int ch) {
+ return null;
+ }
+
+ protected IOException error(String message) {
+ return null;
+ }
+
+ public void free() { }
+
+ public void close() throws IOException { }
+
+ static final class ObjectDefinition {
+ }
+
+ class ReadInputStream extends InputStream {
+
+ ReadInputStream() { }
+
+ public int read() throws IOException {
+ return 1;
+ }
+
+ public int read(byte[] buffer, int offset, int length) throws IOException {
+ return 1;
+ }
+
+ public void close() throws IOException { }
+ }
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/HessianInput.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/HessianInput.java
new file mode 100644
index 00000000000..e10a11ad706
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/HessianInput.java
@@ -0,0 +1,229 @@
+package com.caucho.hessian.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+
+public class HessianInput extends AbstractHessianInput {
+
+ public HessianInput() {
+ }
+
+ public HessianInput(InputStream is) { }
+
+ public void init(InputStream is) { }
+
+ public String getMethod() {
+ return null;
+ }
+
+ public Throwable getReplyFault() {
+ return null;
+ }
+
+ public int readCall() throws IOException {
+ return 0;
+ }
+
+ public void skipOptionalCall() throws IOException { }
+
+ public String readMethod() throws IOException {
+ return null;
+ }
+
+ public void startCall() throws IOException { }
+
+ public void completeCall() throws IOException { }
+
+ public Object readReply(Class expectedClass) throws Throwable {
+ return null;
+ }
+
+ public void startReply() throws Throwable { }
+
+ public void startReplyBody() throws Throwable { }
+
+ private Throwable prepareFault() throws IOException {
+ return null;
+ }
+
+ public void completeReply() throws IOException { }
+
+ public void completeValueReply() throws IOException { }
+
+ public String readHeader() throws IOException {
+ return null;
+ }
+
+ public void readNull() throws IOException { }
+
+ public boolean readBoolean() throws IOException {
+ return true;
+ }
+
+ public short readShort() throws IOException {
+ return 11111;
+ }
+
+ public int readInt() throws IOException {
+ return 1;
+ }
+
+ public long readLong() throws IOException {
+ return 1L;
+ }
+
+ public float readFloat() throws IOException {
+ return 1.1F;
+ }
+
+ public double readDouble() throws IOException {
+ return 1.1;
+ }
+
+ public long readUTCDate() throws IOException {
+ return 1L;
+ }
+
+ public int readChar() throws IOException {
+ return 1;
+ }
+
+ public int readString(char[] buffer, int offset, int length) throws IOException {
+ return 1;
+ }
+
+ public String readString() throws IOException {
+ return null;
+ }
+
+ public byte[] readBytes() throws IOException {
+ return null;
+ }
+
+ public int readByte() throws IOException {
+ return 1;
+ }
+
+ public int readBytes(byte[] buffer, int offset, int length) throws IOException {
+ return 1;
+ }
+
+ private HashMap readFault() throws IOException {
+ return null;
+ }
+
+ public Object readObject(Class cl) throws IOException {
+ return null;
+ }
+
+ public Object readObject() throws IOException {
+ return null;
+ }
+
+ public Object readRemote() throws IOException {
+ return null;
+ }
+
+ public Object readRef() throws IOException {
+ return null;
+ }
+
+ public int readListStart() throws IOException {
+ return 1;
+ }
+
+ public int readMapStart() throws IOException {
+ return 1;
+ }
+
+ public boolean isEnd() throws IOException {
+ return true;
+ }
+
+ public void readEnd() throws IOException { }
+
+ public void readMapEnd() throws IOException { }
+
+ public void readListEnd() throws IOException { }
+
+ public int addRef(Object ref) {
+ return 1;
+ }
+
+ public void setRef(int i, Object ref) { }
+
+ public void resetReferences() { }
+
+ public Object resolveRemote(String type, String url) throws IOException {
+ return null;
+ }
+
+ public String readType() throws IOException {
+ return null;
+ }
+
+ public int readLength() throws IOException {
+ return 1;
+ }
+
+ private int parseInt() throws IOException {
+ return 1;
+ }
+
+ private long parseLong() throws IOException {
+ return 1L;
+ }
+
+ private double parseDouble() throws IOException {
+ return 1.1;
+ }
+
+ private int parseChar() throws IOException {
+ return 1;
+ }
+
+ private int parseUTF8Char() throws IOException {
+ return 1;
+ }
+
+ private int parseByte() throws IOException {
+ return 1;
+ }
+
+ public InputStream readInputStream() throws IOException {
+ return null;
+ }
+
+ int read(byte[] buffer, int offset, int length) throws IOException {
+ return 1;
+ }
+
+ final int read() throws IOException {
+ return 1;
+ }
+
+ public void close() { }
+
+ public Reader getReader() {
+ return null;
+ }
+
+ protected IOException expect(String expect, int ch) {
+ return null;
+ }
+
+ protected String codeName(int ch) {
+ return null;
+ }
+
+ protected IOException error(String message) {
+ return null;
+ }
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/HessianRemoteResolver.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/HessianRemoteResolver.java
new file mode 100644
index 00000000000..3a6b7f86604
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/HessianRemoteResolver.java
@@ -0,0 +1,8 @@
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+public interface HessianRemoteResolver {
+ Object lookup(String var1, String var2) throws IOException;
+}
+
diff --git a/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/SerializerFactory.java b/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/SerializerFactory.java
new file mode 100644
index 00000000000..2e87899e6dd
--- /dev/null
+++ b/java/ql/test/stubs/hessian-4.0.38/com/caucho/hessian/io/SerializerFactory.java
@@ -0,0 +1,5 @@
+package com.caucho.hessian.io;
+
+public class SerializerFactory {
+
+}
diff --git a/java/ql/test/stubs/json-io-4.10.0/com/cedarsoftware/util/io/JsonReader.java b/java/ql/test/stubs/json-io-4.10.0/com/cedarsoftware/util/io/JsonReader.java
new file mode 100644
index 00000000000..75bfce50eeb
--- /dev/null
+++ b/java/ql/test/stubs/json-io-4.10.0/com/cedarsoftware/util/io/JsonReader.java
@@ -0,0 +1,41 @@
+package com.cedarsoftware.util.io;
+
+import java.io.Closeable;
+import java.io.InputStream;
+import java.util.Map;
+
+public class JsonReader implements Closeable {
+
+ public static Object jsonToJava(String json) {
+ return null;
+ }
+
+ public static Object jsonToJava(String json, Map optionalArgs) {
+ return null;
+ }
+
+ public static Object jsonToJava(InputStream inputStream, Map optionalArgs) {
+ return null;
+ }
+
+ public JsonReader() { }
+
+ public JsonReader(InputStream inp) { }
+
+ public JsonReader(Map optionalArgs) { }
+
+ public JsonReader(InputStream inp, boolean useMaps) { }
+
+ public JsonReader(InputStream inp, Map optionalArgs) { }
+
+ public JsonReader(String inp, Map optionalArgs) { }
+
+ public JsonReader(byte[] inp, Map optionalArgs) { }
+
+ public Object readObject() {
+ return null;
+ }
+
+ public void close() { }
+}
+
diff --git a/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/Yaml.java b/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/Yaml.java
new file mode 100644
index 00000000000..43c10a12142
--- /dev/null
+++ b/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/Yaml.java
@@ -0,0 +1,77 @@
+package org.ho.yaml;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.Reader;
+
+public class Yaml {
+
+ public Yaml() {
+ }
+
+ public static Object load(Reader var0) {
+ return null;
+ }
+
+ public static Object load(InputStream var0) {
+ return null;
+ }
+
+ public static Object load(File var0) throws FileNotFoundException {
+ return null;
+ }
+
+ public static Object load(String var0) {
+ return null;
+ }
+
+ public static T loadType(Reader var0, Class var1) {
+ return null;
+ }
+
+ public static T loadType(InputStream var0, Class var1) throws FileNotFoundException {
+ return null;
+ }
+
+ public static T loadType(File var0, Class var1) throws FileNotFoundException {
+ return null;
+ }
+
+ public static T loadType(String var0, Class var1) {
+ return null;
+ }
+
+ public static YamlStream loadStream(Reader var0) {
+ return null;
+ }
+
+ public static YamlStream loadStream(InputStream var0) {
+ return null;
+ }
+
+ public static YamlStream loadStream(File var0) throws FileNotFoundException {
+ return null;
+ }
+
+ public static YamlStream loadStream(String var0) {
+ return null;
+ }
+
+ public static YamlStream loadStreamOfType(Reader var0, Class var1) {
+ return null;
+ }
+
+ public static YamlStream loadStreamOfType(InputStream var0, Class var1) {
+ return null;
+ }
+
+ public static YamlStream loadStreamOfType(File var0, Class var1) throws FileNotFoundException {
+ return null;
+ }
+
+ public static YamlStream loadStreamOfType(String var0, Class var1) throws FileNotFoundException {
+ return null;
+ }
+}
+
diff --git a/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlConfig.java b/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlConfig.java
new file mode 100644
index 00000000000..bdf3059eec7
--- /dev/null
+++ b/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlConfig.java
@@ -0,0 +1,122 @@
+package org.ho.yaml;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.util.Iterator;
+
+public class YamlConfig implements YamlOperations, Cloneable {
+
+ public YamlConfig() { }
+
+ public Object load(YamlDecoder var1) {
+ return null;
+ }
+
+ public Object load(InputStream var1) {
+ return null;
+ }
+
+ public Object load(Reader var1) {
+ return null;
+ }
+
+ public Object load(File var1) throws FileNotFoundException {
+ return null;
+ }
+
+ public Object load(String var1) {
+ return null;
+ }
+
+ public T loadType(YamlDecoder var1, Class var2) {
+ return null;
+ }
+
+ public T loadType(InputStream var1, Class var2) {
+ return null;
+ }
+
+ public T loadType(Reader var1, Class var2) {
+ return null;
+ }
+
+ public T loadType(File var1, Class var2) throws FileNotFoundException {
+ return null;
+ }
+
+ public T loadType(String var1, Class var2) {
+ return null;
+ }
+
+ public YamlStream loadStream(YamlDecoder var1) {
+ return null;
+ }
+
+ public YamlStream loadStream(Reader var1) {
+ return null;
+ }
+
+ public YamlStream loadStream(InputStream var1) {
+ return null;
+ }
+
+ public YamlStream loadStream(File var1) throws FileNotFoundException {
+ return null;
+ }
+
+ public YamlStream loadStream(String var1) {
+ return null;
+ }
+
+ public YamlStream loadStreamOfType(YamlDecoder var1, Class var2) {
+ return null;
+ }
+
+ public YamlStream loadStreamOfType(Reader var1, Class var2) {
+ return null;
+ }
+
+ public YamlStream loadStreamOfType(InputStream var1, Class var2) {
+ return null;
+ }
+
+ public YamlStream loadStreamOfType(File var1, Class var2) throws FileNotFoundException {
+ return null;
+ }
+
+ public YamlStream loadStreamOfType(String var1, Class var2) {
+ return null;
+ }
+
+ public void dump(Object var1, File var2) throws FileNotFoundException { }
+
+ public void dump(Object var1, File var2, boolean var3) throws FileNotFoundException { }
+
+ public String dump(Object var1) {
+ return null;
+ }
+
+ public String dump(Object var1, boolean var2) {
+ return null;
+ }
+
+ public void dump(Object var1, OutputStream var2, boolean var3) { }
+
+ public void dump(Object var1, OutputStream var2) { }
+
+ public void dumpStream(Iterator var1, File var2, boolean var3) throws FileNotFoundException { }
+
+ public void dumpStream(Iterator var1, File var2) throws FileNotFoundException { }
+
+ public String dumpStream(Iterator var1) {
+ return null;
+ }
+
+ public String dumpStream(Iterator var1, boolean var2) {
+ return null;
+ }
+}
+
diff --git a/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlDecoder.java b/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlDecoder.java
new file mode 100644
index 00000000000..b3bd4982a77
--- /dev/null
+++ b/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlDecoder.java
@@ -0,0 +1,16 @@
+package org.ho.yaml;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+public class YamlDecoder {
+
+ YamlDecoder(InputStream var1, YamlConfig var2) { }
+
+ public YamlDecoder(InputStream var1) { }
+
+ public YamlDecoder(Reader var1) { }
+
+ public YamlDecoder(Reader var1, YamlConfig var2) { }
+}
+
diff --git a/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlOperations.java b/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlOperations.java
new file mode 100644
index 00000000000..b4af6ee7125
--- /dev/null
+++ b/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlOperations.java
@@ -0,0 +1,63 @@
+package org.ho.yaml;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.util.Iterator;
+
+public interface YamlOperations {
+ Object load(InputStream var1);
+
+ Object load(Reader var1);
+
+ Object load(File var1) throws FileNotFoundException;
+
+ Object load(String var1);
+
+ T loadType(InputStream var1, Class var2);
+
+ T loadType(Reader var1, Class var2);
+
+ T loadType(File var1, Class var2) throws FileNotFoundException;
+
+ T loadType(String var1, Class var2);
+
+ YamlStream loadStream(InputStream var1);
+
+ YamlStream loadStream(Reader var1);
+
+ YamlStream loadStream(File var1) throws FileNotFoundException;
+
+ YamlStream loadStream(String var1);
+
+ YamlStream loadStreamOfType(InputStream var1, Class var2);
+
+ YamlStream loadStreamOfType(Reader var1, Class var2);
+
+ YamlStream loadStreamOfType(File var1, Class var2) throws FileNotFoundException;
+
+ YamlStream loadStreamOfType(String var1, Class var2);
+
+ void dump(Object var1, File var2) throws FileNotFoundException;
+
+ void dump(Object var1, File var2, boolean var3) throws FileNotFoundException;
+
+ String dump(Object var1);
+
+ String dump(Object var1, boolean var2);
+
+ void dumpStream(Iterator var1, File var2) throws FileNotFoundException;
+
+ void dumpStream(Iterator var1, File var2, boolean var3) throws FileNotFoundException;
+
+ String dumpStream(Iterator var1);
+
+ String dumpStream(Iterator var1, boolean var2);
+
+ void dump(Object var1, OutputStream var2);
+
+ void dump(Object var1, OutputStream var2, boolean var3);
+}
+
diff --git a/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlStream.java b/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlStream.java
new file mode 100644
index 00000000000..53f0ddf144e
--- /dev/null
+++ b/java/ql/test/stubs/jyaml-1.3/org/ho/yaml/YamlStream.java
@@ -0,0 +1,7 @@
+package org.ho.yaml;
+
+import java.util.Iterator;
+
+public interface YamlStream extends Iterable, Iterator {
+}
+
diff --git a/java/ql/test/stubs/yamlbeans-1.09/com/esotericsoftware/yamlbeans/YamlConfig.java b/java/ql/test/stubs/yamlbeans-1.09/com/esotericsoftware/yamlbeans/YamlConfig.java
new file mode 100644
index 00000000000..3488ef83dab
--- /dev/null
+++ b/java/ql/test/stubs/yamlbeans-1.09/com/esotericsoftware/yamlbeans/YamlConfig.java
@@ -0,0 +1,7 @@
+package com.esotericsoftware.yamlbeans;
+
+public class YamlConfig {
+
+ public YamlConfig() { }
+}
+
diff --git a/java/ql/test/stubs/yamlbeans-1.09/com/esotericsoftware/yamlbeans/YamlException.java b/java/ql/test/stubs/yamlbeans-1.09/com/esotericsoftware/yamlbeans/YamlException.java
new file mode 100644
index 00000000000..cb2e54f97e0
--- /dev/null
+++ b/java/ql/test/stubs/yamlbeans-1.09/com/esotericsoftware/yamlbeans/YamlException.java
@@ -0,0 +1,18 @@
+package com.esotericsoftware.yamlbeans;
+
+import java.io.IOException;
+
+public class YamlException extends IOException {
+ public YamlException() {
+ }
+
+ public YamlException(String message, Throwable cause) {
+ }
+
+ public YamlException(String message) {
+ }
+
+ public YamlException(Throwable cause) {
+ }
+}
+
diff --git a/java/ql/test/stubs/yamlbeans-1.09/com/esotericsoftware/yamlbeans/YamlReader.java b/java/ql/test/stubs/yamlbeans-1.09/com/esotericsoftware/yamlbeans/YamlReader.java
new file mode 100644
index 00000000000..edaeeb911e0
--- /dev/null
+++ b/java/ql/test/stubs/yamlbeans-1.09/com/esotericsoftware/yamlbeans/YamlReader.java
@@ -0,0 +1,28 @@
+package com.esotericsoftware.yamlbeans;
+
+
+import java.io.Reader;
+
+public class YamlReader {
+
+ public YamlReader(Reader reader) { }
+
+ public YamlReader(Reader reader, YamlConfig config) { }
+
+ public YamlReader(String yaml) { }
+
+ public YamlReader(String yaml, YamlConfig config) { }
+
+ public Object read() throws YamlException {
+ return null;
+ }
+
+ public T read(Class type) throws YamlException {
+ return null;
+ }
+
+ public T read(Class type, Class elementType) throws YamlException {
+ return null;
+ }
+}
+