diff --git a/java/ql/lib/change-notes/2025-01-16-file-constructor-sanitizer.md b/java/ql/lib/change-notes/2025-01-16-file-constructor-sanitizer.md new file mode 100644 index 000000000000..8296f447e24a --- /dev/null +++ b/java/ql/lib/change-notes/2025-01-16-file-constructor-sanitizer.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added a path injection sanitizer for the `child` argument of a `java.io.File` constructor if that argument does not contain path traversal sequences. diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index e408d1dd58f5..3582e2b78ac6 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -88,7 +88,10 @@ extensions: - ["java.io", "DataInput", True, "readUTF", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "DataInputStream", False, "DataInputStream", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "File", False, "File", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["java.io", "File", False, "File", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] + # We model this taint step in QL as `FileConstructorChildArgumentStep` in the `PathSanitizer` library + # since we need to sanitize the use of this argument but not later uses of the same SSA variable, + # which is not currently possible in Java with a standard sanitizer due to use-use flow. + # - ["java.io", "File", False, "File", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - ["java.io", "File", True, "getAbsoluteFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "getAbsolutePath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "getCanonicalFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll index c931817e00b4..d081a6289ecd 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll @@ -29,6 +29,7 @@ private module Frameworks { private import semmle.code.java.frameworks.ratpack.RatpackExec private import semmle.code.java.frameworks.stapler.Stapler private import semmle.code.java.security.ListOfConstantsSanitizer + private import semmle.code.java.security.PathSanitizer } /** diff --git a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll index 9072de7ce520..cd173823f2dc 100644 --- a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll +++ b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll @@ -6,6 +6,7 @@ private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.dataflow.SSA private import semmle.code.java.frameworks.kotlin.IO private import semmle.code.java.frameworks.kotlin.Text +private import semmle.code.java.dataflow.Nullness /** A sanitizer that protects against path injection vulnerabilities. */ abstract class PathInjectionSanitizer extends DataFlow::Node { } @@ -137,14 +138,7 @@ private class AllowedPrefixSanitizer extends PathInjectionSanitizer { * been checked for a trusted prefix. */ private predicate dotDotCheckGuard(Guard g, Expr e, boolean branch) { - // Local taint-flow is used here to handle cases where the validated expression comes from the - // expression reaching the sink, but it's not the same one, e.g.: - // Path path = source(); - // String strPath = path.toString(); - // if (!strPath.contains("..") && strPath.startsWith("/safe/dir")) - // sink(path); - branch = g.(PathTraversalGuard).getBranch() and - localTaintFlowToPathGuard(e, g) and + pathTraversalGuard(g, e, branch) and exists(Guard previousGuard | previousGuard.(AllowedPrefixGuard).controls(g.getBasicBlock(), true) or @@ -352,3 +346,40 @@ private class FileGetNameSanitizer extends PathInjectionSanitizer { ) } } + +/** Holds if `g` is a guard that checks for `..` components. */ +private predicate pathTraversalGuard(Guard g, Expr e, boolean branch) { + // Local taint-flow is used here to handle cases where the validated expression comes from the + // expression reaching the sink, but it's not the same one, e.g.: + // Path path = source(); + // String strPath = path.toString(); + // if (!strPath.contains("..") && strPath.startsWith("/safe/dir")) + // sink(path); + branch = g.(PathTraversalGuard).getBranch() and + localTaintFlowToPathGuard(e, g) +} + +/** + * A taint step from a child argument of a `java.io.File` constructor to the + * constructor call. + * + * This step only applies if the argument is not guarded by a check for `..` + * components (`PathTraversalGuard`), or it does not have any internal `..` + * components removed from it (`PathNormalizeSanitizer`), or if the parent + * argument of the constructor may be null. + */ +private class FileConstructorChildArgumentStep extends AdditionalTaintStep { + override predicate step(DataFlow::Node n1, DataFlow::Node n2) { + exists(ConstructorCall constrCall | + constrCall.getConstructedType() instanceof TypeFile and + n1.asExpr() = constrCall.getArgument(1) and + n2.asExpr() = constrCall + | + not n1 = DataFlow::BarrierGuard::getABarrierNode() and + not n1 = ValidationMethod::getAValidatedNode() and + not TaintTracking::localExprTaint(any(PathNormalizeSanitizer p), n1.asExpr()) + or + DataFlow::localExprFlow(nullExpr(), constrCall.getArgument(0)) + ) + } +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-200/InsecureWebResourceResponse.expected b/java/ql/test/experimental/query-tests/security/CWE-200/InsecureWebResourceResponse.expected index 66a0b307b1d8..6913a6622936 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-200/InsecureWebResourceResponse.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-200/InsecureWebResourceResponse.expected @@ -22,7 +22,7 @@ edges | InsecureWebResourceResponse.java:65:41:65:43 | url : String | InsecureWebResourceResponse.java:65:31:65:44 | parse(...) : Uri | provenance | MaD:2 | | InsecureWebResourceResponse.java:66:51:66:84 | new FileInputStream(...) : FileInputStream | InsecureWebResourceResponse.java:68:71:68:81 | inputStream | provenance | | | InsecureWebResourceResponse.java:66:71:66:73 | uri : Uri | InsecureWebResourceResponse.java:66:71:66:83 | getPath(...) : String | provenance | MaD:4 | -| InsecureWebResourceResponse.java:66:71:66:83 | getPath(...) : String | InsecureWebResourceResponse.java:66:51:66:84 | new FileInputStream(...) : FileInputStream | provenance | MaD:7 | +| InsecureWebResourceResponse.java:66:71:66:83 | getPath(...) : String | InsecureWebResourceResponse.java:66:51:66:84 | new FileInputStream(...) : FileInputStream | provenance | MaD:6 | | InsecureWebResourceResponse.java:75:20:75:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | provenance | AdditionalTaintStep | | InsecureWebResourceResponse.java:75:20:75:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | provenance | AdditionalTaintStep | | InsecureWebResourceResponse.java:75:20:75:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | provenance | AdditionalTaintStep | @@ -32,11 +32,10 @@ edges | InsecureWebResourceResponse.java:84:77:84:86 | url : String | InsecureWebResourceResponse.java:86:41:86:43 | url : String | provenance | | | InsecureWebResourceResponse.java:86:31:86:44 | parse(...) : Uri | InsecureWebResourceResponse.java:88:66:88:68 | uri : Uri | provenance | | | InsecureWebResourceResponse.java:86:41:86:43 | url : String | InsecureWebResourceResponse.java:86:31:86:44 | parse(...) : Uri | provenance | MaD:2 | -| InsecureWebResourceResponse.java:88:42:88:90 | new File(...) : File | InsecureWebResourceResponse.java:89:75:89:83 | cacheFile : File | provenance | | | InsecureWebResourceResponse.java:88:66:88:68 | uri : Uri | InsecureWebResourceResponse.java:88:66:88:89 | getLastPathSegment(...) : String | provenance | MaD:3 | -| InsecureWebResourceResponse.java:88:66:88:89 | getLastPathSegment(...) : String | InsecureWebResourceResponse.java:88:42:88:90 | new File(...) : File | provenance | MaD:6 | +| InsecureWebResourceResponse.java:88:66:88:89 | getLastPathSegment(...) : String | InsecureWebResourceResponse.java:89:75:89:83 | cacheFile : File | provenance | AdditionalTaintStep | | InsecureWebResourceResponse.java:89:55:89:84 | new FileInputStream(...) : FileInputStream | InsecureWebResourceResponse.java:91:75:91:85 | inputStream | provenance | | -| InsecureWebResourceResponse.java:89:75:89:83 | cacheFile : File | InsecureWebResourceResponse.java:89:55:89:84 | new FileInputStream(...) : FileInputStream | provenance | MaD:7 | +| InsecureWebResourceResponse.java:89:75:89:83 | cacheFile : File | InsecureWebResourceResponse.java:89:55:89:84 | new FileInputStream(...) : FileInputStream | provenance | MaD:6 | | InsecureWebResourceResponse.java:101:20:101:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | provenance | AdditionalTaintStep | | InsecureWebResourceResponse.java:101:20:101:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | provenance | AdditionalTaintStep | | InsecureWebResourceResponse.java:101:20:101:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | provenance | AdditionalTaintStep | @@ -47,11 +46,11 @@ edges | InsecureWebResourceResponse.java:112:31:112:44 | parse(...) : Uri | InsecureWebResourceResponse.java:113:35:113:37 | uri : Uri | provenance | | | InsecureWebResourceResponse.java:112:41:112:43 | url : String | InsecureWebResourceResponse.java:112:31:112:44 | parse(...) : Uri | provenance | MaD:2 | | InsecureWebResourceResponse.java:113:35:113:37 | uri : Uri | InsecureWebResourceResponse.java:113:35:113:47 | getPath(...) : String | provenance | MaD:4 | -| InsecureWebResourceResponse.java:113:35:113:47 | getPath(...) : String | InsecureWebResourceResponse.java:113:35:113:60 | substring(...) : String | provenance | MaD:8 | +| InsecureWebResourceResponse.java:113:35:113:47 | getPath(...) : String | InsecureWebResourceResponse.java:113:35:113:60 | substring(...) : String | provenance | MaD:7 | | InsecureWebResourceResponse.java:113:35:113:60 | substring(...) : String | InsecureWebResourceResponse.java:115:75:115:78 | path : String | provenance | | | InsecureWebResourceResponse.java:115:55:115:108 | new FileInputStream(...) : FileInputStream | InsecureWebResourceResponse.java:117:75:117:85 | inputStream | provenance | | -| InsecureWebResourceResponse.java:115:75:115:78 | path : String | InsecureWebResourceResponse.java:115:75:115:107 | substring(...) : String | provenance | MaD:8 | -| InsecureWebResourceResponse.java:115:75:115:107 | substring(...) : String | InsecureWebResourceResponse.java:115:55:115:108 | new FileInputStream(...) : FileInputStream | provenance | MaD:7 | +| InsecureWebResourceResponse.java:115:75:115:78 | path : String | InsecureWebResourceResponse.java:115:75:115:107 | substring(...) : String | provenance | MaD:7 | +| InsecureWebResourceResponse.java:115:75:115:107 | substring(...) : String | InsecureWebResourceResponse.java:115:55:115:108 | new FileInputStream(...) : FileInputStream | provenance | MaD:6 | | InsecureWebResourceResponse.java:127:20:127:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | provenance | AdditionalTaintStep | | InsecureWebResourceResponse.java:127:20:127:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | provenance | AdditionalTaintStep | | InsecureWebResourceResponse.java:127:20:127:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | provenance | AdditionalTaintStep | @@ -79,11 +78,10 @@ edges | InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | InsecureWebResourceResponse.java:194:31:194:37 | request : WebResourceRequest | provenance | | | InsecureWebResourceResponse.java:194:31:194:37 | request : WebResourceRequest | InsecureWebResourceResponse.java:194:31:194:46 | getUrl(...) : Uri | provenance | MaD:5 | | InsecureWebResourceResponse.java:194:31:194:46 | getUrl(...) : Uri | InsecureWebResourceResponse.java:196:66:196:68 | uri : Uri | provenance | | -| InsecureWebResourceResponse.java:196:42:196:90 | new File(...) : File | InsecureWebResourceResponse.java:197:75:197:83 | cacheFile : File | provenance | | | InsecureWebResourceResponse.java:196:66:196:68 | uri : Uri | InsecureWebResourceResponse.java:196:66:196:89 | getLastPathSegment(...) : String | provenance | MaD:3 | -| InsecureWebResourceResponse.java:196:66:196:89 | getLastPathSegment(...) : String | InsecureWebResourceResponse.java:196:42:196:90 | new File(...) : File | provenance | MaD:6 | +| InsecureWebResourceResponse.java:196:66:196:89 | getLastPathSegment(...) : String | InsecureWebResourceResponse.java:197:75:197:83 | cacheFile : File | provenance | AdditionalTaintStep | | InsecureWebResourceResponse.java:197:55:197:84 | new FileInputStream(...) : FileInputStream | InsecureWebResourceResponse.java:199:75:199:85 | inputStream | provenance | | -| InsecureWebResourceResponse.java:197:75:197:83 | cacheFile : File | InsecureWebResourceResponse.java:197:55:197:84 | new FileInputStream(...) : FileInputStream | provenance | MaD:7 | +| InsecureWebResourceResponse.java:197:75:197:83 | cacheFile : File | InsecureWebResourceResponse.java:197:55:197:84 | new FileInputStream(...) : FileInputStream | provenance | MaD:6 | | InsecureWebResourceResponse.java:209:20:209:22 | url : String | InsecureWebResourceResponse.java:63:77:63:86 | url : String | provenance | AdditionalTaintStep | | InsecureWebResourceResponse.java:209:20:209:22 | url : String | InsecureWebResourceResponse.java:84:77:84:86 | url : String | provenance | AdditionalTaintStep | | InsecureWebResourceResponse.java:209:20:209:22 | url : String | InsecureWebResourceResponse.java:110:77:110:86 | url : String | provenance | AdditionalTaintStep | @@ -100,7 +98,7 @@ edges | InsecureWebResourceResponse.java:234:33:234:35 | url : String | InsecureWebResourceResponse.java:234:23:234:36 | parse(...) : Uri | provenance | MaD:2 | | InsecureWebResourceResponse.java:235:43:235:76 | new FileInputStream(...) : FileInputStream | InsecureWebResourceResponse.java:237:63:237:73 | inputStream | provenance | | | InsecureWebResourceResponse.java:235:63:235:65 | uri : Uri | InsecureWebResourceResponse.java:235:63:235:75 | getPath(...) : String | provenance | MaD:4 | -| InsecureWebResourceResponse.java:235:63:235:75 | getPath(...) : String | InsecureWebResourceResponse.java:235:43:235:76 | new FileInputStream(...) : FileInputStream | provenance | MaD:7 | +| InsecureWebResourceResponse.java:235:63:235:75 | getPath(...) : String | InsecureWebResourceResponse.java:235:43:235:76 | new FileInputStream(...) : FileInputStream | provenance | MaD:6 | | InsecureWebViewActivity.java:27:27:27:37 | getIntent(...) : Intent | InsecureWebViewActivity.java:27:27:27:64 | getStringExtra(...) : String | provenance | MaD:1 | | InsecureWebViewActivity.java:27:27:27:64 | getStringExtra(...) : String | InsecureWebViewActivity.java:28:20:28:27 | inputUrl : String | provenance | | | InsecureWebViewActivity.java:28:20:28:27 | inputUrl : String | InsecureWebViewActivity.java:42:28:42:37 | url : String | provenance | | @@ -111,16 +109,15 @@ edges | InsecureWebViewActivity.java:55:41:55:43 | url : String | InsecureWebViewActivity.java:55:31:55:44 | parse(...) : Uri | provenance | MaD:2 | | InsecureWebViewActivity.java:56:51:56:84 | new FileInputStream(...) : FileInputStream | InsecureWebViewActivity.java:58:71:58:81 | inputStream | provenance | | | InsecureWebViewActivity.java:56:71:56:73 | uri : Uri | InsecureWebViewActivity.java:56:71:56:83 | getPath(...) : String | provenance | MaD:4 | -| InsecureWebViewActivity.java:56:71:56:83 | getPath(...) : String | InsecureWebViewActivity.java:56:51:56:84 | new FileInputStream(...) : FileInputStream | provenance | MaD:7 | +| InsecureWebViewActivity.java:56:71:56:83 | getPath(...) : String | InsecureWebViewActivity.java:56:51:56:84 | new FileInputStream(...) : FileInputStream | provenance | MaD:6 | models | 1 | Summary: android.content; Intent; true; getStringExtra; (String); ; Argument[this].SyntheticField[android.content.Intent.extras].MapValue; ReturnValue; value; manual | | 2 | Summary: android.net; Uri; false; parse; ; ; Argument[0]; ReturnValue; taint; manual | | 3 | Summary: android.net; Uri; true; getLastPathSegment; ; ; Argument[this]; ReturnValue; taint; manual | | 4 | Summary: android.net; Uri; true; getPath; ; ; Argument[this]; ReturnValue; taint; manual | | 5 | Summary: android.webkit; WebResourceRequest; false; getUrl; ; ; Argument[this]; ReturnValue; taint; manual | -| 6 | Summary: java.io; File; false; File; ; ; Argument[1]; Argument[this]; taint; manual | -| 7 | Summary: java.io; FileInputStream; true; FileInputStream; ; ; Argument[0]; Argument[this]; taint; manual | -| 8 | Summary: java.lang; String; false; substring; ; ; Argument[this]; ReturnValue; taint; manual | +| 6 | Summary: java.io; FileInputStream; true; FileInputStream; ; ; Argument[0]; Argument[this]; taint; manual | +| 7 | Summary: java.lang; String; false; substring; ; ; Argument[this]; ReturnValue; taint; manual | nodes | InsecureWebResourceResponse.java:28:27:28:37 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent | | InsecureWebResourceResponse.java:28:27:28:64 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String | @@ -145,7 +142,6 @@ nodes | InsecureWebResourceResponse.java:84:77:84:86 | url : String | semmle.label | url : String | | InsecureWebResourceResponse.java:86:31:86:44 | parse(...) : Uri | semmle.label | parse(...) : Uri | | InsecureWebResourceResponse.java:86:41:86:43 | url : String | semmle.label | url : String | -| InsecureWebResourceResponse.java:88:42:88:90 | new File(...) : File | semmle.label | new File(...) : File | | InsecureWebResourceResponse.java:88:66:88:68 | uri : Uri | semmle.label | uri : Uri | | InsecureWebResourceResponse.java:88:66:88:89 | getLastPathSegment(...) : String | semmle.label | getLastPathSegment(...) : String | | InsecureWebResourceResponse.java:89:55:89:84 | new FileInputStream(...) : FileInputStream | semmle.label | new FileInputStream(...) : FileInputStream | @@ -174,7 +170,6 @@ nodes | InsecureWebResourceResponse.java:192:77:192:102 | request : WebResourceRequest | semmle.label | request : WebResourceRequest | | InsecureWebResourceResponse.java:194:31:194:37 | request : WebResourceRequest | semmle.label | request : WebResourceRequest | | InsecureWebResourceResponse.java:194:31:194:46 | getUrl(...) : Uri | semmle.label | getUrl(...) : Uri | -| InsecureWebResourceResponse.java:196:42:196:90 | new File(...) : File | semmle.label | new File(...) : File | | InsecureWebResourceResponse.java:196:66:196:68 | uri : Uri | semmle.label | uri : Uri | | InsecureWebResourceResponse.java:196:66:196:89 | getLastPathSegment(...) : String | semmle.label | getLastPathSegment(...) : String | | InsecureWebResourceResponse.java:197:55:197:84 | new FileInputStream(...) : FileInputStream | semmle.label | new FileInputStream(...) : FileInputStream | diff --git a/java/ql/test/library-tests/frameworks/jdk/java.io/test.expected b/java/ql/test/library-tests/frameworks/jdk/java.io/test.expected index 4b2f3cd5f12c..e0f578543513 100644 --- a/java/ql/test/library-tests/frameworks/jdk/java.io/test.expected +++ b/java/ql/test/library-tests/frameworks/jdk/java.io/test.expected @@ -14,32 +14,31 @@ models | 13 | Summary: java.io; DataInput; true; readUTF; (); ; Argument[this]; ReturnValue; taint; manual | | 14 | Summary: java.io; DataInputStream; false; DataInputStream; ; ; Argument[0]; Argument[this]; taint; manual | | 15 | Summary: java.io; File; false; File; ; ; Argument[0]; Argument[this]; taint; manual | -| 16 | Summary: java.io; File; false; File; ; ; Argument[1]; Argument[this]; taint; manual | -| 17 | Summary: java.io; File; true; getAbsoluteFile; ; ; Argument[this]; ReturnValue; taint; manual | -| 18 | Summary: java.io; File; true; getAbsolutePath; ; ; Argument[this]; ReturnValue; taint; manual | -| 19 | Summary: java.io; File; true; getCanonicalFile; ; ; Argument[this]; ReturnValue; taint; manual | -| 20 | Summary: java.io; File; true; getCanonicalPath; ; ; Argument[this]; ReturnValue; taint; manual | -| 21 | Summary: java.io; File; true; getName; (); ; Argument[this]; ReturnValue; taint; manual | -| 22 | Summary: java.io; File; true; toPath; ; ; Argument[this]; ReturnValue; taint; manual | -| 23 | Summary: java.io; File; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | -| 24 | Summary: java.io; File; true; toURI; ; ; Argument[this]; ReturnValue; taint; manual | -| 25 | Summary: java.io; FilterOutputStream; true; FilterOutputStream; (OutputStream); ; Argument[0]; Argument[this]; taint; manual | -| 26 | Summary: java.io; IOException; false; IOException; (String); ; Argument[0]; Argument[this].SyntheticField[java.lang.Throwable.message]; value; manual | -| 27 | Summary: java.io; InputStream; true; read; (byte[]); ; Argument[this]; Argument[0]; taint; manual | -| 28 | Summary: java.io; InputStream; true; read; (byte[],int,int); ; Argument[this]; Argument[0]; taint; manual | -| 29 | Summary: java.io; InputStream; true; readAllBytes; ; ; Argument[this]; ReturnValue; taint; manual | -| 30 | Summary: java.io; InputStream; true; readNBytes; (byte[],int,int); ; Argument[this]; Argument[0]; taint; manual | -| 31 | Summary: java.io; InputStream; true; readNBytes; (int); ; Argument[this]; ReturnValue; taint; manual | -| 32 | Summary: java.io; InputStream; true; transferTo; (OutputStream); ; Argument[this]; Argument[0]; taint; manual | -| 33 | Summary: java.io; InputStreamReader; false; InputStreamReader; ; ; Argument[0]; Argument[this]; taint; manual | -| 34 | Summary: java.io; ObjectInput; true; read; ; ; Argument[this]; Argument[0]; taint; manual | -| 35 | Summary: java.io; ObjectInputStream; false; ObjectInputStream; ; ; Argument[0]; Argument[this]; taint; manual | -| 36 | Summary: java.io; OutputStream; true; write; (byte[]); ; Argument[0]; Argument[this]; taint; manual | -| 37 | Summary: java.io; OutputStream; true; write; (byte[],int,int); ; Argument[0]; Argument[this]; taint; manual | -| 38 | Summary: java.io; OutputStream; true; write; (int); ; Argument[0]; Argument[this]; taint; manual | -| 39 | Summary: java.io; Reader; true; read; ; ; Argument[this]; Argument[0]; taint; manual | -| 40 | Summary: java.io; StringReader; false; StringReader; ; ; Argument[0]; Argument[this]; taint; manual | -| 41 | Summary: java.io; Writer; true; write; ; ; Argument[0]; Argument[this]; taint; manual | +| 16 | Summary: java.io; File; true; getAbsoluteFile; ; ; Argument[this]; ReturnValue; taint; manual | +| 17 | Summary: java.io; File; true; getAbsolutePath; ; ; Argument[this]; ReturnValue; taint; manual | +| 18 | Summary: java.io; File; true; getCanonicalFile; ; ; Argument[this]; ReturnValue; taint; manual | +| 19 | Summary: java.io; File; true; getCanonicalPath; ; ; Argument[this]; ReturnValue; taint; manual | +| 20 | Summary: java.io; File; true; getName; (); ; Argument[this]; ReturnValue; taint; manual | +| 21 | Summary: java.io; File; true; toPath; ; ; Argument[this]; ReturnValue; taint; manual | +| 22 | Summary: java.io; File; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | +| 23 | Summary: java.io; File; true; toURI; ; ; Argument[this]; ReturnValue; taint; manual | +| 24 | Summary: java.io; FilterOutputStream; true; FilterOutputStream; (OutputStream); ; Argument[0]; Argument[this]; taint; manual | +| 25 | Summary: java.io; IOException; false; IOException; (String); ; Argument[0]; Argument[this].SyntheticField[java.lang.Throwable.message]; value; manual | +| 26 | Summary: java.io; InputStream; true; read; (byte[]); ; Argument[this]; Argument[0]; taint; manual | +| 27 | Summary: java.io; InputStream; true; read; (byte[],int,int); ; Argument[this]; Argument[0]; taint; manual | +| 28 | Summary: java.io; InputStream; true; readAllBytes; ; ; Argument[this]; ReturnValue; taint; manual | +| 29 | Summary: java.io; InputStream; true; readNBytes; (byte[],int,int); ; Argument[this]; Argument[0]; taint; manual | +| 30 | Summary: java.io; InputStream; true; readNBytes; (int); ; Argument[this]; ReturnValue; taint; manual | +| 31 | Summary: java.io; InputStream; true; transferTo; (OutputStream); ; Argument[this]; Argument[0]; taint; manual | +| 32 | Summary: java.io; InputStreamReader; false; InputStreamReader; ; ; Argument[0]; Argument[this]; taint; manual | +| 33 | Summary: java.io; ObjectInput; true; read; ; ; Argument[this]; Argument[0]; taint; manual | +| 34 | Summary: java.io; ObjectInputStream; false; ObjectInputStream; ; ; Argument[0]; Argument[this]; taint; manual | +| 35 | Summary: java.io; OutputStream; true; write; (byte[]); ; Argument[0]; Argument[this]; taint; manual | +| 36 | Summary: java.io; OutputStream; true; write; (byte[],int,int); ; Argument[0]; Argument[this]; taint; manual | +| 37 | Summary: java.io; OutputStream; true; write; (int); ; Argument[0]; Argument[this]; taint; manual | +| 38 | Summary: java.io; Reader; true; read; ; ; Argument[this]; Argument[0]; taint; manual | +| 39 | Summary: java.io; StringReader; false; StringReader; ; ; Argument[0]; Argument[this]; taint; manual | +| 40 | Summary: java.io; Writer; true; write; ; ; Argument[0]; Argument[this]; taint; manual | edges | Test.java:50:21:50:42 | (...)... : InputStream | Test.java:51:34:51:35 | in : InputStream | provenance | | | Test.java:50:21:50:42 | (...)... : InputStream | Test.java:52:9:52:11 | out | provenance | inputStreamWrapper | @@ -180,302 +179,298 @@ edges | Test.java:274:19:274:26 | source(...) : Object | Test.java:274:13:274:26 | (...)... : URI | provenance | | | Test.java:275:10:275:21 | new File(...) : File | Test.java:276:9:276:11 | out | provenance | | | Test.java:275:19:275:20 | in : URI | Test.java:275:10:275:21 | new File(...) : File | provenance | MaD:15 | -| Test.java:281:16:281:32 | (...)... : String | Test.java:282:32:282:33 | in : String | provenance | | +| Test.java:281:16:281:32 | (...)... : String | Test.java:283:9:283:11 | out | provenance | AdditionalTaintStep | | Test.java:281:25:281:32 | source(...) : Object | Test.java:281:16:281:32 | (...)... : String | provenance | | -| Test.java:282:10:282:34 | new File(...) : File | Test.java:283:9:283:11 | out | provenance | | -| Test.java:282:32:282:33 | in : String | Test.java:282:10:282:34 | new File(...) : File | provenance | MaD:16 | -| Test.java:288:16:288:32 | (...)... : String | Test.java:289:34:289:35 | in : String | provenance | | +| Test.java:288:16:288:32 | (...)... : String | Test.java:290:9:290:11 | out | provenance | AdditionalTaintStep | | Test.java:288:25:288:32 | source(...) : Object | Test.java:288:16:288:32 | (...)... : String | provenance | | -| Test.java:289:10:289:36 | new File(...) : File | Test.java:290:9:290:11 | out | provenance | | -| Test.java:289:34:289:35 | in : String | Test.java:289:10:289:36 | new File(...) : File | provenance | MaD:16 | | Test.java:295:14:295:28 | (...)... : File | Test.java:296:10:296:11 | in : File | provenance | | | Test.java:295:21:295:28 | source(...) : Object | Test.java:295:14:295:28 | (...)... : File | provenance | | -| Test.java:296:10:296:11 | in : File | Test.java:296:10:296:29 | getAbsoluteFile(...) : File | provenance | MaD:17 | +| Test.java:296:10:296:11 | in : File | Test.java:296:10:296:29 | getAbsoluteFile(...) : File | provenance | MaD:16 | | Test.java:296:10:296:29 | getAbsoluteFile(...) : File | Test.java:297:9:297:11 | out | provenance | | | Test.java:302:14:302:28 | (...)... : File | Test.java:303:10:303:11 | in : File | provenance | | | Test.java:302:21:302:28 | source(...) : Object | Test.java:302:14:302:28 | (...)... : File | provenance | | -| Test.java:303:10:303:11 | in : File | Test.java:303:10:303:29 | getAbsolutePath(...) : String | provenance | MaD:18 | +| Test.java:303:10:303:11 | in : File | Test.java:303:10:303:29 | getAbsolutePath(...) : String | provenance | MaD:17 | | Test.java:303:10:303:29 | getAbsolutePath(...) : String | Test.java:304:9:304:11 | out | provenance | | | Test.java:309:14:309:28 | (...)... : File | Test.java:310:10:310:11 | in : File | provenance | | | Test.java:309:21:309:28 | source(...) : Object | Test.java:309:14:309:28 | (...)... : File | provenance | | -| Test.java:310:10:310:11 | in : File | Test.java:310:10:310:30 | getCanonicalFile(...) : File | provenance | MaD:19 | +| Test.java:310:10:310:11 | in : File | Test.java:310:10:310:30 | getCanonicalFile(...) : File | provenance | MaD:18 | | Test.java:310:10:310:30 | getCanonicalFile(...) : File | Test.java:311:9:311:11 | out | provenance | | | Test.java:316:14:316:28 | (...)... : File | Test.java:317:10:317:11 | in : File | provenance | | | Test.java:316:21:316:28 | source(...) : Object | Test.java:316:14:316:28 | (...)... : File | provenance | | -| Test.java:317:10:317:11 | in : File | Test.java:317:10:317:30 | getCanonicalPath(...) : String | provenance | MaD:20 | +| Test.java:317:10:317:11 | in : File | Test.java:317:10:317:30 | getCanonicalPath(...) : String | provenance | MaD:19 | | Test.java:317:10:317:30 | getCanonicalPath(...) : String | Test.java:318:9:318:11 | out | provenance | | | Test.java:323:14:323:28 | (...)... : File | Test.java:324:10:324:11 | in : File | provenance | | | Test.java:323:21:323:28 | source(...) : Object | Test.java:323:14:323:28 | (...)... : File | provenance | | -| Test.java:324:10:324:11 | in : File | Test.java:324:10:324:21 | getName(...) : String | provenance | MaD:21 | +| Test.java:324:10:324:11 | in : File | Test.java:324:10:324:21 | getName(...) : String | provenance | MaD:20 | | Test.java:324:10:324:21 | getName(...) : String | Test.java:325:9:325:11 | out | provenance | | | Test.java:330:14:330:28 | (...)... : File | Test.java:331:10:331:11 | in : File | provenance | | | Test.java:330:21:330:28 | source(...) : Object | Test.java:330:14:330:28 | (...)... : File | provenance | | -| Test.java:331:10:331:11 | in : File | Test.java:331:10:331:20 | toPath(...) : Path | provenance | MaD:22 | +| Test.java:331:10:331:11 | in : File | Test.java:331:10:331:20 | toPath(...) : Path | provenance | MaD:21 | | Test.java:331:10:331:20 | toPath(...) : Path | Test.java:332:9:332:11 | out | provenance | | | Test.java:337:14:337:28 | (...)... : File | Test.java:338:10:338:11 | in : File | provenance | | | Test.java:337:21:337:28 | source(...) : Object | Test.java:337:14:337:28 | (...)... : File | provenance | | -| Test.java:338:10:338:11 | in : File | Test.java:338:10:338:22 | toString(...) : String | provenance | MaD:23 | +| Test.java:338:10:338:11 | in : File | Test.java:338:10:338:22 | toString(...) : String | provenance | MaD:22 | | Test.java:338:10:338:22 | toString(...) : String | Test.java:339:9:339:11 | out | provenance | | | Test.java:344:14:344:28 | (...)... : File | Test.java:345:10:345:11 | in : File | provenance | | | Test.java:344:21:344:28 | source(...) : Object | Test.java:344:14:344:28 | (...)... : File | provenance | | -| Test.java:345:10:345:11 | in : File | Test.java:345:10:345:19 | toURI(...) : URI | provenance | MaD:24 | +| Test.java:345:10:345:11 | in : File | Test.java:345:10:345:19 | toURI(...) : URI | provenance | MaD:23 | | Test.java:345:10:345:19 | toURI(...) : URI | Test.java:346:9:346:11 | out | provenance | | | Test.java:351:22:351:44 | (...)... : OutputStream | Test.java:352:33:352:34 | in : OutputStream | provenance | | | Test.java:351:37:351:44 | source(...) : Object | Test.java:351:22:351:44 | (...)... : OutputStream | provenance | | | Test.java:352:10:352:35 | new FilterOutputStream(...) : FilterOutputStream | Test.java:353:9:353:11 | out | provenance | | -| Test.java:352:33:352:34 | in : OutputStream | Test.java:352:10:352:35 | new FilterOutputStream(...) : FilterOutputStream | provenance | MaD:25 | +| Test.java:352:33:352:34 | in : OutputStream | Test.java:352:10:352:35 | new FilterOutputStream(...) : FilterOutputStream | provenance | MaD:24 | | Test.java:358:16:358:32 | (...)... : String | Test.java:359:26:359:27 | in : String | provenance | | | Test.java:358:25:358:32 | source(...) : Object | Test.java:358:16:358:32 | (...)... : String | provenance | | | Test.java:359:10:359:28 | new IOException(...) : IOException [java.lang.Throwable.message] : String | Test.java:360:37:360:39 | out : IOException [java.lang.Throwable.message] : String | provenance | | -| Test.java:359:26:359:27 | in : String | Test.java:359:10:359:28 | new IOException(...) : IOException [java.lang.Throwable.message] : String | provenance | MaD:26 | +| Test.java:359:26:359:27 | in : String | Test.java:359:10:359:28 | new IOException(...) : IOException [java.lang.Throwable.message] : String | provenance | MaD:25 | | Test.java:360:37:360:39 | out : IOException [java.lang.Throwable.message] : String | Test.java:360:9:360:40 | getThrowable_messageDefault(...) | provenance | MaD:1 | | Test.java:365:25:365:50 | (...)... : DataInputStream | Test.java:366:4:366:5 | in : DataInputStream | provenance | | | Test.java:365:43:365:50 | source(...) : Object | Test.java:365:25:365:50 | (...)... : DataInputStream | provenance | | -| Test.java:366:4:366:5 | in : DataInputStream | Test.java:366:12:366:14 | out [post update] : byte[] | provenance | MaD:27 | +| Test.java:366:4:366:5 | in : DataInputStream | Test.java:366:12:366:14 | out [post update] : byte[] | provenance | MaD:26 | | Test.java:366:12:366:14 | out [post update] : byte[] | Test.java:367:9:367:11 | out | provenance | | | Test.java:372:27:372:54 | (...)... : FilterInputStream | Test.java:373:4:373:5 | in : FilterInputStream | provenance | | | Test.java:372:47:372:54 | source(...) : Object | Test.java:372:27:372:54 | (...)... : FilterInputStream | provenance | | -| Test.java:373:4:373:5 | in : FilterInputStream | Test.java:373:12:373:14 | out [post update] : byte[] | provenance | MaD:27 | +| Test.java:373:4:373:5 | in : FilterInputStream | Test.java:373:12:373:14 | out [post update] : byte[] | provenance | MaD:26 | | Test.java:373:12:373:14 | out [post update] : byte[] | Test.java:374:9:374:11 | out | provenance | | | Test.java:379:21:379:42 | (...)... : InputStream | Test.java:380:4:380:5 | in : InputStream | provenance | | | Test.java:379:35:379:42 | source(...) : Object | Test.java:379:21:379:42 | (...)... : InputStream | provenance | | -| Test.java:380:4:380:5 | in : InputStream | Test.java:380:12:380:14 | out [post update] : byte[] | provenance | MaD:27 | +| Test.java:380:4:380:5 | in : InputStream | Test.java:380:12:380:14 | out [post update] : byte[] | provenance | MaD:26 | | Test.java:380:12:380:14 | out [post update] : byte[] | Test.java:381:9:381:11 | out | provenance | | | Test.java:386:29:386:58 | (...)... : BufferedInputStream | Test.java:387:4:387:5 | in : BufferedInputStream | provenance | | | Test.java:386:51:386:58 | source(...) : Object | Test.java:386:29:386:58 | (...)... : BufferedInputStream | provenance | | -| Test.java:387:4:387:5 | in : BufferedInputStream | Test.java:387:12:387:14 | out [post update] : byte[] | provenance | MaD:28 | +| Test.java:387:4:387:5 | in : BufferedInputStream | Test.java:387:12:387:14 | out [post update] : byte[] | provenance | MaD:27 | | Test.java:387:12:387:14 | out [post update] : byte[] | Test.java:388:9:388:11 | out | provenance | | | Test.java:393:30:393:60 | (...)... : ByteArrayInputStream | Test.java:394:4:394:5 | in : ByteArrayInputStream | provenance | | | Test.java:393:53:393:60 | source(...) : Object | Test.java:393:30:393:60 | (...)... : ByteArrayInputStream | provenance | | -| Test.java:394:4:394:5 | in : ByteArrayInputStream | Test.java:394:12:394:14 | out [post update] : byte[] | provenance | MaD:28 | +| Test.java:394:4:394:5 | in : ByteArrayInputStream | Test.java:394:12:394:14 | out [post update] : byte[] | provenance | MaD:27 | | Test.java:394:12:394:14 | out [post update] : byte[] | Test.java:395:9:395:11 | out | provenance | | | Test.java:400:25:400:50 | (...)... : DataInputStream | Test.java:401:4:401:5 | in : DataInputStream | provenance | | | Test.java:400:43:400:50 | source(...) : Object | Test.java:400:25:400:50 | (...)... : DataInputStream | provenance | | -| Test.java:401:4:401:5 | in : DataInputStream | Test.java:401:12:401:14 | out [post update] : byte[] | provenance | MaD:28 | +| Test.java:401:4:401:5 | in : DataInputStream | Test.java:401:12:401:14 | out [post update] : byte[] | provenance | MaD:27 | | Test.java:401:12:401:14 | out [post update] : byte[] | Test.java:402:9:402:11 | out | provenance | | | Test.java:407:27:407:54 | (...)... : FilterInputStream | Test.java:408:4:408:5 | in : FilterInputStream | provenance | | | Test.java:407:47:407:54 | source(...) : Object | Test.java:407:27:407:54 | (...)... : FilterInputStream | provenance | | -| Test.java:408:4:408:5 | in : FilterInputStream | Test.java:408:12:408:14 | out [post update] : byte[] | provenance | MaD:28 | +| Test.java:408:4:408:5 | in : FilterInputStream | Test.java:408:12:408:14 | out [post update] : byte[] | provenance | MaD:27 | | Test.java:408:12:408:14 | out [post update] : byte[] | Test.java:409:9:409:11 | out | provenance | | | Test.java:414:21:414:42 | (...)... : InputStream | Test.java:415:4:415:5 | in : InputStream | provenance | | | Test.java:414:35:414:42 | source(...) : Object | Test.java:414:21:414:42 | (...)... : InputStream | provenance | | -| Test.java:415:4:415:5 | in : InputStream | Test.java:415:12:415:14 | out [post update] : byte[] | provenance | MaD:28 | +| Test.java:415:4:415:5 | in : InputStream | Test.java:415:12:415:14 | out [post update] : byte[] | provenance | MaD:27 | | Test.java:415:12:415:14 | out [post update] : byte[] | Test.java:416:9:416:11 | out | provenance | | | Test.java:421:27:421:54 | (...)... : ObjectInputStream | Test.java:422:4:422:5 | in : ObjectInputStream | provenance | | | Test.java:421:47:421:54 | source(...) : Object | Test.java:421:27:421:54 | (...)... : ObjectInputStream | provenance | | -| Test.java:422:4:422:5 | in : ObjectInputStream | Test.java:422:12:422:14 | out [post update] : byte[] | provenance | MaD:28 | -| Test.java:422:4:422:5 | in : ObjectInputStream | Test.java:422:12:422:14 | out [post update] : byte[] | provenance | MaD:34 | +| Test.java:422:4:422:5 | in : ObjectInputStream | Test.java:422:12:422:14 | out [post update] : byte[] | provenance | MaD:27 | +| Test.java:422:4:422:5 | in : ObjectInputStream | Test.java:422:12:422:14 | out [post update] : byte[] | provenance | MaD:33 | | Test.java:422:12:422:14 | out [post update] : byte[] | Test.java:423:9:423:11 | out | provenance | | | Test.java:428:30:428:60 | (...)... : ByteArrayInputStream | Test.java:429:10:429:11 | in : ByteArrayInputStream | provenance | | | Test.java:428:53:428:60 | source(...) : Object | Test.java:428:30:428:60 | (...)... : ByteArrayInputStream | provenance | | -| Test.java:429:10:429:11 | in : ByteArrayInputStream | Test.java:429:10:429:26 | readAllBytes(...) : byte[] | provenance | MaD:29 | +| Test.java:429:10:429:11 | in : ByteArrayInputStream | Test.java:429:10:429:26 | readAllBytes(...) : byte[] | provenance | MaD:28 | | Test.java:429:10:429:26 | readAllBytes(...) : byte[] | Test.java:430:9:430:11 | out | provenance | | | Test.java:435:21:435:42 | (...)... : InputStream | Test.java:436:10:436:11 | in : InputStream | provenance | | | Test.java:435:35:435:42 | source(...) : Object | Test.java:435:21:435:42 | (...)... : InputStream | provenance | | -| Test.java:436:10:436:11 | in : InputStream | Test.java:436:10:436:26 | readAllBytes(...) : byte[] | provenance | MaD:29 | +| Test.java:436:10:436:11 | in : InputStream | Test.java:436:10:436:26 | readAllBytes(...) : byte[] | provenance | MaD:28 | | Test.java:436:10:436:26 | readAllBytes(...) : byte[] | Test.java:437:9:437:11 | out | provenance | | | Test.java:442:30:442:60 | (...)... : ByteArrayInputStream | Test.java:443:4:443:5 | in : ByteArrayInputStream | provenance | | | Test.java:442:53:442:60 | source(...) : Object | Test.java:442:30:442:60 | (...)... : ByteArrayInputStream | provenance | | -| Test.java:443:4:443:5 | in : ByteArrayInputStream | Test.java:443:18:443:20 | out [post update] : byte[] | provenance | MaD:30 | +| Test.java:443:4:443:5 | in : ByteArrayInputStream | Test.java:443:18:443:20 | out [post update] : byte[] | provenance | MaD:29 | | Test.java:443:18:443:20 | out [post update] : byte[] | Test.java:444:9:444:11 | out | provenance | | | Test.java:449:21:449:42 | (...)... : InputStream | Test.java:450:4:450:5 | in : InputStream | provenance | | | Test.java:449:35:449:42 | source(...) : Object | Test.java:449:21:449:42 | (...)... : InputStream | provenance | | -| Test.java:450:4:450:5 | in : InputStream | Test.java:450:18:450:20 | out [post update] : byte[] | provenance | MaD:30 | +| Test.java:450:4:450:5 | in : InputStream | Test.java:450:18:450:20 | out [post update] : byte[] | provenance | MaD:29 | | Test.java:450:18:450:20 | out [post update] : byte[] | Test.java:451:9:451:11 | out | provenance | | | Test.java:456:21:456:42 | (...)... : InputStream | Test.java:457:10:457:11 | in : InputStream | provenance | | | Test.java:456:35:456:42 | source(...) : Object | Test.java:456:21:456:42 | (...)... : InputStream | provenance | | -| Test.java:457:10:457:11 | in : InputStream | Test.java:457:10:457:25 | readNBytes(...) : byte[] | provenance | MaD:31 | +| Test.java:457:10:457:11 | in : InputStream | Test.java:457:10:457:25 | readNBytes(...) : byte[] | provenance | MaD:30 | | Test.java:457:10:457:25 | readNBytes(...) : byte[] | Test.java:458:9:458:11 | out | provenance | | | Test.java:463:30:463:60 | (...)... : ByteArrayInputStream | Test.java:464:4:464:5 | in : ByteArrayInputStream | provenance | | | Test.java:463:53:463:60 | source(...) : Object | Test.java:463:30:463:60 | (...)... : ByteArrayInputStream | provenance | | -| Test.java:464:4:464:5 | in : ByteArrayInputStream | Test.java:464:18:464:20 | out [post update] : OutputStream | provenance | MaD:32 | +| Test.java:464:4:464:5 | in : ByteArrayInputStream | Test.java:464:18:464:20 | out [post update] : OutputStream | provenance | MaD:31 | | Test.java:464:18:464:20 | out [post update] : OutputStream | Test.java:465:9:465:11 | out | provenance | | | Test.java:470:21:470:42 | (...)... : InputStream | Test.java:471:4:471:5 | in : InputStream | provenance | | | Test.java:470:35:470:42 | source(...) : Object | Test.java:470:21:470:42 | (...)... : InputStream | provenance | | -| Test.java:471:4:471:5 | in : InputStream | Test.java:471:18:471:20 | out [post update] : OutputStream | provenance | MaD:32 | +| Test.java:471:4:471:5 | in : InputStream | Test.java:471:18:471:20 | out [post update] : OutputStream | provenance | MaD:31 | | Test.java:471:18:471:20 | out [post update] : OutputStream | Test.java:472:9:472:11 | out | provenance | | | Test.java:477:21:477:42 | (...)... : InputStream | Test.java:478:32:478:33 | in : InputStream | provenance | | | Test.java:477:35:477:42 | source(...) : Object | Test.java:477:21:477:42 | (...)... : InputStream | provenance | | | Test.java:478:10:478:34 | new InputStreamReader(...) : InputStreamReader | Test.java:479:9:479:11 | out | provenance | | -| Test.java:478:32:478:33 | in : InputStream | Test.java:478:10:478:34 | new InputStreamReader(...) : InputStreamReader | provenance | MaD:33 | +| Test.java:478:32:478:33 | in : InputStream | Test.java:478:10:478:34 | new InputStreamReader(...) : InputStreamReader | provenance | MaD:32 | | Test.java:484:21:484:42 | (...)... : InputStream | Test.java:485:32:485:33 | in : InputStream | provenance | | | Test.java:484:35:484:42 | source(...) : Object | Test.java:484:21:484:42 | (...)... : InputStream | provenance | | | Test.java:485:10:485:50 | new InputStreamReader(...) : InputStreamReader | Test.java:486:9:486:11 | out | provenance | | -| Test.java:485:32:485:33 | in : InputStream | Test.java:485:10:485:50 | new InputStreamReader(...) : InputStreamReader | provenance | MaD:33 | +| Test.java:485:32:485:33 | in : InputStream | Test.java:485:10:485:50 | new InputStreamReader(...) : InputStreamReader | provenance | MaD:32 | | Test.java:491:21:491:42 | (...)... : InputStream | Test.java:492:32:492:33 | in : InputStream | provenance | | | Test.java:491:35:491:42 | source(...) : Object | Test.java:491:21:491:42 | (...)... : InputStream | provenance | | | Test.java:492:10:492:57 | new InputStreamReader(...) : InputStreamReader | Test.java:493:9:493:11 | out | provenance | | -| Test.java:492:32:492:33 | in : InputStream | Test.java:492:10:492:57 | new InputStreamReader(...) : InputStreamReader | provenance | MaD:33 | +| Test.java:492:32:492:33 | in : InputStream | Test.java:492:10:492:57 | new InputStreamReader(...) : InputStreamReader | provenance | MaD:32 | | Test.java:498:21:498:42 | (...)... : InputStream | Test.java:499:32:499:33 | in : InputStream | provenance | | | Test.java:498:35:498:42 | source(...) : Object | Test.java:498:21:498:42 | (...)... : InputStream | provenance | | | Test.java:499:10:499:49 | new InputStreamReader(...) : InputStreamReader | Test.java:500:9:500:11 | out | provenance | | -| Test.java:499:32:499:33 | in : InputStream | Test.java:499:10:499:49 | new InputStreamReader(...) : InputStreamReader | provenance | MaD:33 | +| Test.java:499:32:499:33 | in : InputStream | Test.java:499:10:499:49 | new InputStreamReader(...) : InputStreamReader | provenance | MaD:32 | | Test.java:505:21:505:42 | (...)... : ObjectInput | Test.java:506:4:506:5 | in : ObjectInput | provenance | | | Test.java:505:35:505:42 | source(...) : Object | Test.java:505:21:505:42 | (...)... : ObjectInput | provenance | | -| Test.java:506:4:506:5 | in : ObjectInput | Test.java:506:12:506:14 | out [post update] : byte[] | provenance | MaD:34 | +| Test.java:506:4:506:5 | in : ObjectInput | Test.java:506:12:506:14 | out [post update] : byte[] | provenance | MaD:33 | | Test.java:506:12:506:14 | out [post update] : byte[] | Test.java:507:9:507:11 | out | provenance | | | Test.java:512:21:512:42 | (...)... : ObjectInput | Test.java:513:4:513:5 | in : ObjectInput | provenance | | | Test.java:512:35:512:42 | source(...) : Object | Test.java:512:21:512:42 | (...)... : ObjectInput | provenance | | -| Test.java:513:4:513:5 | in : ObjectInput | Test.java:513:12:513:14 | out [post update] : byte[] | provenance | MaD:34 | +| Test.java:513:4:513:5 | in : ObjectInput | Test.java:513:12:513:14 | out [post update] : byte[] | provenance | MaD:33 | | Test.java:513:12:513:14 | out [post update] : byte[] | Test.java:514:9:514:11 | out | provenance | | | Test.java:519:27:519:54 | (...)... : ObjectInputStream | Test.java:520:4:520:5 | in : ObjectInputStream | provenance | | | Test.java:519:47:519:54 | source(...) : Object | Test.java:519:27:519:54 | (...)... : ObjectInputStream | provenance | | -| Test.java:520:4:520:5 | in : ObjectInputStream | Test.java:520:12:520:14 | out [post update] : byte[] | provenance | MaD:28 | -| Test.java:520:4:520:5 | in : ObjectInputStream | Test.java:520:12:520:14 | out [post update] : byte[] | provenance | MaD:34 | +| Test.java:520:4:520:5 | in : ObjectInputStream | Test.java:520:12:520:14 | out [post update] : byte[] | provenance | MaD:27 | +| Test.java:520:4:520:5 | in : ObjectInputStream | Test.java:520:12:520:14 | out [post update] : byte[] | provenance | MaD:33 | | Test.java:520:12:520:14 | out [post update] : byte[] | Test.java:521:9:521:11 | out | provenance | | | Test.java:526:21:526:42 | (...)... : InputStream | Test.java:527:32:527:33 | in : InputStream | provenance | | | Test.java:526:21:526:42 | (...)... : InputStream | Test.java:528:9:528:11 | out | provenance | inputStreamWrapper | | Test.java:526:35:526:42 | source(...) : Object | Test.java:526:21:526:42 | (...)... : InputStream | provenance | | | Test.java:527:10:527:34 | new ObjectInputStream(...) : ObjectInputStream | Test.java:528:9:528:11 | out | provenance | | -| Test.java:527:32:527:33 | in : InputStream | Test.java:527:10:527:34 | new ObjectInputStream(...) : ObjectInputStream | provenance | MaD:35 | +| Test.java:527:32:527:33 | in : InputStream | Test.java:527:10:527:34 | new ObjectInputStream(...) : ObjectInputStream | provenance | MaD:34 | | Test.java:533:16:533:32 | (...)... : byte[] | Test.java:534:14:534:15 | in : byte[] | provenance | | | Test.java:533:25:533:32 | source(...) : Object | Test.java:533:16:533:32 | (...)... : byte[] | provenance | | | Test.java:534:4:534:6 | out [post update] : FilterOutputStream | Test.java:535:9:535:11 | out | provenance | | -| Test.java:534:14:534:15 | in : byte[] | Test.java:534:4:534:6 | out [post update] : FilterOutputStream | provenance | MaD:36 | +| Test.java:534:14:534:15 | in : byte[] | Test.java:534:4:534:6 | out [post update] : FilterOutputStream | provenance | MaD:35 | | Test.java:540:16:540:32 | (...)... : byte[] | Test.java:541:14:541:15 | in : byte[] | provenance | | | Test.java:540:25:540:32 | source(...) : Object | Test.java:540:16:540:32 | (...)... : byte[] | provenance | | | Test.java:541:4:541:6 | out [post update] : ObjectOutputStream | Test.java:542:9:542:11 | out | provenance | | -| Test.java:541:14:541:15 | in : byte[] | Test.java:541:4:541:6 | out [post update] : ObjectOutputStream | provenance | MaD:36 | +| Test.java:541:14:541:15 | in : byte[] | Test.java:541:4:541:6 | out [post update] : ObjectOutputStream | provenance | MaD:35 | | Test.java:547:16:547:32 | (...)... : byte[] | Test.java:548:14:548:15 | in : byte[] | provenance | | | Test.java:547:25:547:32 | source(...) : Object | Test.java:547:16:547:32 | (...)... : byte[] | provenance | | | Test.java:548:4:548:6 | out [post update] : OutputStream | Test.java:549:9:549:11 | out | provenance | | -| Test.java:548:14:548:15 | in : byte[] | Test.java:548:4:548:6 | out [post update] : OutputStream | provenance | MaD:36 | +| Test.java:548:14:548:15 | in : byte[] | Test.java:548:4:548:6 | out [post update] : OutputStream | provenance | MaD:35 | | Test.java:554:16:554:32 | (...)... : byte[] | Test.java:555:14:555:15 | in : byte[] | provenance | | | Test.java:554:25:554:32 | source(...) : Object | Test.java:554:16:554:32 | (...)... : byte[] | provenance | | | Test.java:555:4:555:6 | out [post update] : PrintStream | Test.java:556:9:556:11 | out | provenance | | -| Test.java:555:14:555:15 | in : byte[] | Test.java:555:4:555:6 | out [post update] : PrintStream | provenance | MaD:36 | +| Test.java:555:14:555:15 | in : byte[] | Test.java:555:4:555:6 | out [post update] : PrintStream | provenance | MaD:35 | | Test.java:561:16:561:32 | (...)... : byte[] | Test.java:562:14:562:15 | in : byte[] | provenance | | | Test.java:561:25:561:32 | source(...) : Object | Test.java:561:16:561:32 | (...)... : byte[] | provenance | | | Test.java:562:4:562:6 | out [post update] : ByteArrayOutputStream | Test.java:563:9:563:11 | out | provenance | | -| Test.java:562:14:562:15 | in : byte[] | Test.java:562:4:562:6 | out [post update] : ByteArrayOutputStream | provenance | MaD:37 | +| Test.java:562:14:562:15 | in : byte[] | Test.java:562:4:562:6 | out [post update] : ByteArrayOutputStream | provenance | MaD:36 | | Test.java:568:16:568:32 | (...)... : byte[] | Test.java:569:14:569:15 | in : byte[] | provenance | | | Test.java:568:25:568:32 | source(...) : Object | Test.java:568:16:568:32 | (...)... : byte[] | provenance | | | Test.java:569:4:569:6 | out [post update] : FilterOutputStream | Test.java:570:9:570:11 | out | provenance | | -| Test.java:569:14:569:15 | in : byte[] | Test.java:569:4:569:6 | out [post update] : FilterOutputStream | provenance | MaD:37 | +| Test.java:569:14:569:15 | in : byte[] | Test.java:569:4:569:6 | out [post update] : FilterOutputStream | provenance | MaD:36 | | Test.java:575:16:575:32 | (...)... : byte[] | Test.java:576:14:576:15 | in : byte[] | provenance | | | Test.java:575:25:575:32 | source(...) : Object | Test.java:575:16:575:32 | (...)... : byte[] | provenance | | | Test.java:576:4:576:6 | out [post update] : ObjectOutputStream | Test.java:577:9:577:11 | out | provenance | | -| Test.java:576:14:576:15 | in : byte[] | Test.java:576:4:576:6 | out [post update] : ObjectOutputStream | provenance | MaD:37 | +| Test.java:576:14:576:15 | in : byte[] | Test.java:576:4:576:6 | out [post update] : ObjectOutputStream | provenance | MaD:36 | | Test.java:582:16:582:32 | (...)... : byte[] | Test.java:583:14:583:15 | in : byte[] | provenance | | | Test.java:582:25:582:32 | source(...) : Object | Test.java:582:16:582:32 | (...)... : byte[] | provenance | | | Test.java:583:4:583:6 | out [post update] : OutputStream | Test.java:584:9:584:11 | out | provenance | | -| Test.java:583:14:583:15 | in : byte[] | Test.java:583:4:583:6 | out [post update] : OutputStream | provenance | MaD:37 | +| Test.java:583:14:583:15 | in : byte[] | Test.java:583:4:583:6 | out [post update] : OutputStream | provenance | MaD:36 | | Test.java:589:16:589:32 | (...)... : byte[] | Test.java:590:14:590:15 | in : byte[] | provenance | | | Test.java:589:25:589:32 | source(...) : Object | Test.java:589:16:589:32 | (...)... : byte[] | provenance | | | Test.java:590:4:590:6 | out [post update] : PrintStream | Test.java:591:9:591:11 | out | provenance | | -| Test.java:590:14:590:15 | in : byte[] | Test.java:590:4:590:6 | out [post update] : PrintStream | provenance | MaD:37 | +| Test.java:590:14:590:15 | in : byte[] | Test.java:590:4:590:6 | out [post update] : PrintStream | provenance | MaD:36 | | Test.java:596:13:596:26 | (...)... : Number | Test.java:597:14:597:15 | in : Number | provenance | | | Test.java:596:19:596:26 | source(...) : Object | Test.java:596:13:596:26 | (...)... : Number | provenance | | | Test.java:597:4:597:6 | out [post update] : ByteArrayOutputStream | Test.java:598:9:598:11 | out | provenance | | -| Test.java:597:14:597:15 | in : Number | Test.java:597:4:597:6 | out [post update] : ByteArrayOutputStream | provenance | MaD:38 | +| Test.java:597:14:597:15 | in : Number | Test.java:597:4:597:6 | out [post update] : ByteArrayOutputStream | provenance | MaD:37 | | Test.java:603:13:603:26 | (...)... : Number | Test.java:604:14:604:15 | in : Number | provenance | | | Test.java:603:19:603:26 | source(...) : Object | Test.java:603:13:603:26 | (...)... : Number | provenance | | | Test.java:604:4:604:6 | out [post update] : FilterOutputStream | Test.java:605:9:605:11 | out | provenance | | -| Test.java:604:14:604:15 | in : Number | Test.java:604:4:604:6 | out [post update] : FilterOutputStream | provenance | MaD:38 | +| Test.java:604:14:604:15 | in : Number | Test.java:604:4:604:6 | out [post update] : FilterOutputStream | provenance | MaD:37 | | Test.java:610:13:610:26 | (...)... : Number | Test.java:611:14:611:15 | in : Number | provenance | | | Test.java:610:19:610:26 | source(...) : Object | Test.java:610:13:610:26 | (...)... : Number | provenance | | | Test.java:611:4:611:6 | out [post update] : ObjectOutputStream | Test.java:612:9:612:11 | out | provenance | | -| Test.java:611:14:611:15 | in : Number | Test.java:611:4:611:6 | out [post update] : ObjectOutputStream | provenance | MaD:38 | +| Test.java:611:14:611:15 | in : Number | Test.java:611:4:611:6 | out [post update] : ObjectOutputStream | provenance | MaD:37 | | Test.java:617:13:617:26 | (...)... : Number | Test.java:618:14:618:15 | in : Number | provenance | | | Test.java:617:19:617:26 | source(...) : Object | Test.java:617:13:617:26 | (...)... : Number | provenance | | | Test.java:618:4:618:6 | out [post update] : OutputStream | Test.java:619:9:619:11 | out | provenance | | -| Test.java:618:14:618:15 | in : Number | Test.java:618:4:618:6 | out [post update] : OutputStream | provenance | MaD:38 | +| Test.java:618:14:618:15 | in : Number | Test.java:618:4:618:6 | out [post update] : OutputStream | provenance | MaD:37 | | Test.java:624:13:624:26 | (...)... : Number | Test.java:625:14:625:15 | in : Number | provenance | | | Test.java:624:19:624:26 | source(...) : Object | Test.java:624:13:624:26 | (...)... : Number | provenance | | | Test.java:625:4:625:6 | out [post update] : PrintStream | Test.java:626:9:626:11 | out | provenance | | -| Test.java:625:14:625:15 | in : Number | Test.java:625:4:625:6 | out [post update] : PrintStream | provenance | MaD:38 | +| Test.java:625:14:625:15 | in : Number | Test.java:625:4:625:6 | out [post update] : PrintStream | provenance | MaD:37 | | Test.java:631:25:631:50 | (...)... : CharArrayReader | Test.java:632:4:632:5 | in : CharArrayReader | provenance | | | Test.java:631:43:631:50 | source(...) : Object | Test.java:631:25:631:50 | (...)... : CharArrayReader | provenance | | -| Test.java:632:4:632:5 | in : CharArrayReader | Test.java:632:12:632:14 | out [post update] : CharBuffer | provenance | MaD:39 | +| Test.java:632:4:632:5 | in : CharArrayReader | Test.java:632:12:632:14 | out [post update] : CharBuffer | provenance | MaD:38 | | Test.java:632:12:632:14 | out [post update] : CharBuffer | Test.java:633:9:633:11 | out | provenance | | | Test.java:638:27:638:54 | (...)... : InputStreamReader | Test.java:639:4:639:5 | in : InputStreamReader | provenance | | | Test.java:638:47:638:54 | source(...) : Object | Test.java:638:27:638:54 | (...)... : InputStreamReader | provenance | | -| Test.java:639:4:639:5 | in : InputStreamReader | Test.java:639:12:639:14 | out [post update] : CharBuffer | provenance | MaD:39 | +| Test.java:639:4:639:5 | in : InputStreamReader | Test.java:639:12:639:14 | out [post update] : CharBuffer | provenance | MaD:38 | | Test.java:639:12:639:14 | out [post update] : CharBuffer | Test.java:640:9:640:11 | out | provenance | | | Test.java:645:16:645:32 | (...)... : Reader | Test.java:646:4:646:5 | in : Reader | provenance | | | Test.java:645:25:645:32 | source(...) : Object | Test.java:645:16:645:32 | (...)... : Reader | provenance | | -| Test.java:646:4:646:5 | in : Reader | Test.java:646:12:646:14 | out [post update] : CharBuffer | provenance | MaD:39 | +| Test.java:646:4:646:5 | in : Reader | Test.java:646:12:646:14 | out [post update] : CharBuffer | provenance | MaD:38 | | Test.java:646:12:646:14 | out [post update] : CharBuffer | Test.java:647:9:647:11 | out | provenance | | | Test.java:652:24:652:48 | (...)... : BufferedReader | Test.java:653:4:653:5 | in : BufferedReader | provenance | | | Test.java:652:41:652:48 | source(...) : Object | Test.java:652:24:652:48 | (...)... : BufferedReader | provenance | | -| Test.java:653:4:653:5 | in : BufferedReader | Test.java:653:12:653:14 | out [post update] : char[] | provenance | MaD:39 | +| Test.java:653:4:653:5 | in : BufferedReader | Test.java:653:12:653:14 | out [post update] : char[] | provenance | MaD:38 | | Test.java:653:12:653:14 | out [post update] : char[] | Test.java:654:9:654:11 | out | provenance | | | Test.java:659:25:659:50 | (...)... : CharArrayReader | Test.java:660:4:660:5 | in : CharArrayReader | provenance | | | Test.java:659:43:659:50 | source(...) : Object | Test.java:659:25:659:50 | (...)... : CharArrayReader | provenance | | -| Test.java:660:4:660:5 | in : CharArrayReader | Test.java:660:12:660:14 | out [post update] : char[] | provenance | MaD:39 | +| Test.java:660:4:660:5 | in : CharArrayReader | Test.java:660:12:660:14 | out [post update] : char[] | provenance | MaD:38 | | Test.java:660:12:660:14 | out [post update] : char[] | Test.java:661:9:661:11 | out | provenance | | | Test.java:666:27:666:54 | (...)... : InputStreamReader | Test.java:667:4:667:5 | in : InputStreamReader | provenance | | | Test.java:666:47:666:54 | source(...) : Object | Test.java:666:27:666:54 | (...)... : InputStreamReader | provenance | | -| Test.java:667:4:667:5 | in : InputStreamReader | Test.java:667:12:667:14 | out [post update] : char[] | provenance | MaD:39 | +| Test.java:667:4:667:5 | in : InputStreamReader | Test.java:667:12:667:14 | out [post update] : char[] | provenance | MaD:38 | | Test.java:667:12:667:14 | out [post update] : char[] | Test.java:668:9:668:11 | out | provenance | | | Test.java:673:16:673:32 | (...)... : Reader | Test.java:674:4:674:5 | in : Reader | provenance | | | Test.java:673:25:673:32 | source(...) : Object | Test.java:673:16:673:32 | (...)... : Reader | provenance | | -| Test.java:674:4:674:5 | in : Reader | Test.java:674:12:674:14 | out [post update] : char[] | provenance | MaD:39 | +| Test.java:674:4:674:5 | in : Reader | Test.java:674:12:674:14 | out [post update] : char[] | provenance | MaD:38 | | Test.java:674:12:674:14 | out [post update] : char[] | Test.java:675:9:675:11 | out | provenance | | | Test.java:680:16:680:32 | (...)... : Reader | Test.java:681:4:681:5 | in : Reader | provenance | | | Test.java:680:25:680:32 | source(...) : Object | Test.java:680:16:680:32 | (...)... : Reader | provenance | | -| Test.java:681:4:681:5 | in : Reader | Test.java:681:12:681:14 | out [post update] : char[] | provenance | MaD:39 | +| Test.java:681:4:681:5 | in : Reader | Test.java:681:12:681:14 | out [post update] : char[] | provenance | MaD:38 | | Test.java:681:12:681:14 | out [post update] : char[] | Test.java:682:9:682:11 | out | provenance | | | Test.java:687:22:687:44 | (...)... : StringReader | Test.java:688:4:688:5 | in : StringReader | provenance | | | Test.java:687:37:687:44 | source(...) : Object | Test.java:687:22:687:44 | (...)... : StringReader | provenance | | -| Test.java:688:4:688:5 | in : StringReader | Test.java:688:12:688:14 | out [post update] : char[] | provenance | MaD:39 | +| Test.java:688:4:688:5 | in : StringReader | Test.java:688:12:688:14 | out [post update] : char[] | provenance | MaD:38 | | Test.java:688:12:688:14 | out [post update] : char[] | Test.java:689:9:689:11 | out | provenance | | | Test.java:694:16:694:32 | (...)... : String | Test.java:695:27:695:28 | in : String | provenance | | | Test.java:694:25:694:32 | source(...) : Object | Test.java:694:16:694:32 | (...)... : String | provenance | | | Test.java:695:10:695:29 | new StringReader(...) : StringReader | Test.java:696:9:696:11 | out | provenance | | -| Test.java:695:27:695:28 | in : String | Test.java:695:10:695:29 | new StringReader(...) : StringReader | provenance | MaD:40 | +| Test.java:695:27:695:28 | in : String | Test.java:695:10:695:29 | new StringReader(...) : StringReader | provenance | MaD:39 | | Test.java:701:16:701:32 | (...)... : String | Test.java:702:14:702:15 | in : String | provenance | | | Test.java:701:25:701:32 | source(...) : Object | Test.java:701:16:701:32 | (...)... : String | provenance | | | Test.java:702:4:702:6 | out [post update] : CharArrayWriter | Test.java:703:9:703:11 | out | provenance | | -| Test.java:702:14:702:15 | in : String | Test.java:702:4:702:6 | out [post update] : CharArrayWriter | provenance | MaD:41 | +| Test.java:702:14:702:15 | in : String | Test.java:702:4:702:6 | out [post update] : CharArrayWriter | provenance | MaD:40 | | Test.java:708:16:708:32 | (...)... : char[] | Test.java:709:14:709:15 | in : char[] | provenance | | | Test.java:708:25:708:32 | source(...) : Object | Test.java:708:16:708:32 | (...)... : char[] | provenance | | | Test.java:709:4:709:6 | out [post update] : CharArrayWriter | Test.java:710:9:710:11 | out | provenance | | -| Test.java:709:14:709:15 | in : char[] | Test.java:709:4:709:6 | out [post update] : CharArrayWriter | provenance | MaD:41 | +| Test.java:709:14:709:15 | in : char[] | Test.java:709:4:709:6 | out [post update] : CharArrayWriter | provenance | MaD:40 | | Test.java:715:13:715:26 | (...)... : Number | Test.java:716:14:716:15 | in : Number | provenance | | | Test.java:715:19:715:26 | source(...) : Object | Test.java:715:13:715:26 | (...)... : Number | provenance | | | Test.java:716:4:716:6 | out [post update] : CharArrayWriter | Test.java:717:9:717:11 | out | provenance | | -| Test.java:716:14:716:15 | in : Number | Test.java:716:4:716:6 | out [post update] : CharArrayWriter | provenance | MaD:41 | +| Test.java:716:14:716:15 | in : Number | Test.java:716:4:716:6 | out [post update] : CharArrayWriter | provenance | MaD:40 | | Test.java:722:16:722:32 | (...)... : String | Test.java:723:14:723:15 | in : String | provenance | | | Test.java:722:25:722:32 | source(...) : Object | Test.java:722:16:722:32 | (...)... : String | provenance | | | Test.java:723:4:723:6 | out [post update] : PrintWriter | Test.java:724:9:724:11 | out | provenance | | -| Test.java:723:14:723:15 | in : String | Test.java:723:4:723:6 | out [post update] : PrintWriter | provenance | MaD:41 | +| Test.java:723:14:723:15 | in : String | Test.java:723:4:723:6 | out [post update] : PrintWriter | provenance | MaD:40 | | Test.java:729:16:729:32 | (...)... : String | Test.java:730:14:730:15 | in : String | provenance | | | Test.java:729:25:729:32 | source(...) : Object | Test.java:729:16:729:32 | (...)... : String | provenance | | | Test.java:730:4:730:6 | out [post update] : PrintWriter | Test.java:731:9:731:11 | out | provenance | | -| Test.java:730:14:730:15 | in : String | Test.java:730:4:730:6 | out [post update] : PrintWriter | provenance | MaD:41 | +| Test.java:730:14:730:15 | in : String | Test.java:730:4:730:6 | out [post update] : PrintWriter | provenance | MaD:40 | | Test.java:736:16:736:32 | (...)... : char[] | Test.java:737:14:737:15 | in : char[] | provenance | | | Test.java:736:25:736:32 | source(...) : Object | Test.java:736:16:736:32 | (...)... : char[] | provenance | | | Test.java:737:4:737:6 | out [post update] : PrintWriter | Test.java:738:9:738:11 | out | provenance | | -| Test.java:737:14:737:15 | in : char[] | Test.java:737:4:737:6 | out [post update] : PrintWriter | provenance | MaD:41 | +| Test.java:737:14:737:15 | in : char[] | Test.java:737:4:737:6 | out [post update] : PrintWriter | provenance | MaD:40 | | Test.java:743:16:743:32 | (...)... : char[] | Test.java:744:14:744:15 | in : char[] | provenance | | | Test.java:743:25:743:32 | source(...) : Object | Test.java:743:16:743:32 | (...)... : char[] | provenance | | | Test.java:744:4:744:6 | out [post update] : PrintWriter | Test.java:745:9:745:11 | out | provenance | | -| Test.java:744:14:744:15 | in : char[] | Test.java:744:4:744:6 | out [post update] : PrintWriter | provenance | MaD:41 | +| Test.java:744:14:744:15 | in : char[] | Test.java:744:4:744:6 | out [post update] : PrintWriter | provenance | MaD:40 | | Test.java:750:13:750:26 | (...)... : Number | Test.java:751:14:751:15 | in : Number | provenance | | | Test.java:750:19:750:26 | source(...) : Object | Test.java:750:13:750:26 | (...)... : Number | provenance | | | Test.java:751:4:751:6 | out [post update] : PrintWriter | Test.java:752:9:752:11 | out | provenance | | -| Test.java:751:14:751:15 | in : Number | Test.java:751:4:751:6 | out [post update] : PrintWriter | provenance | MaD:41 | +| Test.java:751:14:751:15 | in : Number | Test.java:751:4:751:6 | out [post update] : PrintWriter | provenance | MaD:40 | | Test.java:757:16:757:32 | (...)... : String | Test.java:758:14:758:15 | in : String | provenance | | | Test.java:757:25:757:32 | source(...) : Object | Test.java:757:16:757:32 | (...)... : String | provenance | | | Test.java:758:4:758:6 | out [post update] : Writer | Test.java:759:9:759:11 | out | provenance | | -| Test.java:758:14:758:15 | in : String | Test.java:758:4:758:6 | out [post update] : Writer | provenance | MaD:41 | +| Test.java:758:14:758:15 | in : String | Test.java:758:4:758:6 | out [post update] : Writer | provenance | MaD:40 | | Test.java:764:16:764:32 | (...)... : String | Test.java:765:14:765:15 | in : String | provenance | | | Test.java:764:25:764:32 | source(...) : Object | Test.java:764:16:764:32 | (...)... : String | provenance | | | Test.java:765:4:765:6 | out [post update] : Writer | Test.java:766:9:766:11 | out | provenance | | -| Test.java:765:14:765:15 | in : String | Test.java:765:4:765:6 | out [post update] : Writer | provenance | MaD:41 | +| Test.java:765:14:765:15 | in : String | Test.java:765:4:765:6 | out [post update] : Writer | provenance | MaD:40 | | Test.java:771:16:771:32 | (...)... : char[] | Test.java:772:14:772:15 | in : char[] | provenance | | | Test.java:771:25:771:32 | source(...) : Object | Test.java:771:16:771:32 | (...)... : char[] | provenance | | | Test.java:772:4:772:6 | out [post update] : Writer | Test.java:773:9:773:11 | out | provenance | | -| Test.java:772:14:772:15 | in : char[] | Test.java:772:4:772:6 | out [post update] : Writer | provenance | MaD:41 | +| Test.java:772:14:772:15 | in : char[] | Test.java:772:4:772:6 | out [post update] : Writer | provenance | MaD:40 | | Test.java:778:16:778:32 | (...)... : char[] | Test.java:779:14:779:15 | in : char[] | provenance | | | Test.java:778:25:778:32 | source(...) : Object | Test.java:778:16:778:32 | (...)... : char[] | provenance | | | Test.java:779:4:779:6 | out [post update] : Writer | Test.java:780:9:780:11 | out | provenance | | -| Test.java:779:14:779:15 | in : char[] | Test.java:779:4:779:6 | out [post update] : Writer | provenance | MaD:41 | +| Test.java:779:14:779:15 | in : char[] | Test.java:779:4:779:6 | out [post update] : Writer | provenance | MaD:40 | | Test.java:785:13:785:26 | (...)... : Number | Test.java:786:14:786:15 | in : Number | provenance | | | Test.java:785:19:785:26 | source(...) : Object | Test.java:785:13:785:26 | (...)... : Number | provenance | | | Test.java:786:4:786:6 | out [post update] : Writer | Test.java:787:9:787:11 | out | provenance | | -| Test.java:786:14:786:15 | in : Number | Test.java:786:4:786:6 | out [post update] : Writer | provenance | MaD:41 | +| Test.java:786:14:786:15 | in : Number | Test.java:786:4:786:6 | out [post update] : Writer | provenance | MaD:40 | nodes | Test.java:50:21:50:42 | (...)... : InputStream | semmle.label | (...)... : InputStream | | Test.java:50:35:50:42 | source(...) : Object | semmle.label | source(...) : Object | @@ -644,13 +639,9 @@ nodes | Test.java:276:9:276:11 | out | semmle.label | out | | Test.java:281:16:281:32 | (...)... : String | semmle.label | (...)... : String | | Test.java:281:25:281:32 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:282:10:282:34 | new File(...) : File | semmle.label | new File(...) : File | -| Test.java:282:32:282:33 | in : String | semmle.label | in : String | | Test.java:283:9:283:11 | out | semmle.label | out | | Test.java:288:16:288:32 | (...)... : String | semmle.label | (...)... : String | | Test.java:288:25:288:32 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:289:10:289:36 | new File(...) : File | semmle.label | new File(...) : File | -| Test.java:289:34:289:35 | in : String | semmle.label | in : String | | Test.java:290:9:290:11 | out | semmle.label | out | | Test.java:295:14:295:28 | (...)... : File | semmle.label | (...)... : File | | Test.java:295:21:295:28 | source(...) : Object | semmle.label | source(...) : Object | diff --git a/java/ql/test/library-tests/paths/test.expected b/java/ql/test/library-tests/paths/test.expected index 51682966b6c2..efa06e2ba4ae 100644 --- a/java/ql/test/library-tests/paths/test.expected +++ b/java/ql/test/library-tests/paths/test.expected @@ -1,24 +1,23 @@ models | 1 | Summary: java.io; File; false; File; ; ; Argument[0]; Argument[this]; taint; manual | -| 2 | Summary: java.io; File; false; File; ; ; Argument[1]; Argument[this]; taint; manual | -| 3 | Summary: java.io; File; true; getAbsoluteFile; ; ; Argument[this]; ReturnValue; taint; manual | -| 4 | Summary: java.io; File; true; getAbsolutePath; ; ; Argument[this]; ReturnValue; taint; manual | -| 5 | Summary: java.io; File; true; getCanonicalFile; ; ; Argument[this]; ReturnValue; taint; manual | -| 6 | Summary: java.io; File; true; getCanonicalPath; ; ; Argument[this]; ReturnValue; taint; manual | -| 7 | Summary: java.io; File; true; toPath; ; ; Argument[this]; ReturnValue; taint; manual | -| 8 | Summary: java.io; File; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | -| 9 | Summary: java.io; File; true; toURI; ; ; Argument[this]; ReturnValue; taint; manual | -| 10 | Summary: java.nio.file; FileSystem; true; getPath; (String,String[]); ; Argument[0]; ReturnValue; taint; manual | -| 11 | Summary: java.nio.file; Path; false; toFile; ; ; Argument[this]; ReturnValue; taint; manual | -| 12 | Summary: java.nio.file; Path; true; getParent; ; ; Argument[this]; ReturnValue; taint; manual | -| 13 | Summary: java.nio.file; Path; true; normalize; ; ; Argument[this]; ReturnValue; taint; manual | -| 14 | Summary: java.nio.file; Path; true; resolve; ; ; Argument[0]; ReturnValue; taint; manual | -| 15 | Summary: java.nio.file; Path; true; resolve; ; ; Argument[this]; ReturnValue; taint; manual | -| 16 | Summary: java.nio.file; Path; true; toAbsolutePath; ; ; Argument[this]; ReturnValue; taint; manual | -| 17 | Summary: java.nio.file; Path; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | -| 18 | Summary: java.nio.file; Path; true; toUri; ; ; Argument[this]; ReturnValue; taint; manual | -| 19 | Summary: java.nio.file; Paths; true; get; ; ; Argument[0]; ReturnValue; taint; manual | -| 20 | Summary: java.nio.file; Paths; true; get; ; ; Argument[1].ArrayElement; ReturnValue; taint; manual | +| 2 | Summary: java.io; File; true; getAbsoluteFile; ; ; Argument[this]; ReturnValue; taint; manual | +| 3 | Summary: java.io; File; true; getAbsolutePath; ; ; Argument[this]; ReturnValue; taint; manual | +| 4 | Summary: java.io; File; true; getCanonicalFile; ; ; Argument[this]; ReturnValue; taint; manual | +| 5 | Summary: java.io; File; true; getCanonicalPath; ; ; Argument[this]; ReturnValue; taint; manual | +| 6 | Summary: java.io; File; true; toPath; ; ; Argument[this]; ReturnValue; taint; manual | +| 7 | Summary: java.io; File; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | +| 8 | Summary: java.io; File; true; toURI; ; ; Argument[this]; ReturnValue; taint; manual | +| 9 | Summary: java.nio.file; FileSystem; true; getPath; (String,String[]); ; Argument[0]; ReturnValue; taint; manual | +| 10 | Summary: java.nio.file; Path; false; toFile; ; ; Argument[this]; ReturnValue; taint; manual | +| 11 | Summary: java.nio.file; Path; true; getParent; ; ; Argument[this]; ReturnValue; taint; manual | +| 12 | Summary: java.nio.file; Path; true; normalize; ; ; Argument[this]; ReturnValue; taint; manual | +| 13 | Summary: java.nio.file; Path; true; resolve; ; ; Argument[0]; ReturnValue; taint; manual | +| 14 | Summary: java.nio.file; Path; true; resolve; ; ; Argument[this]; ReturnValue; taint; manual | +| 15 | Summary: java.nio.file; Path; true; toAbsolutePath; ; ; Argument[this]; ReturnValue; taint; manual | +| 16 | Summary: java.nio.file; Path; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | +| 17 | Summary: java.nio.file; Path; true; toUri; ; ; Argument[this]; ReturnValue; taint; manual | +| 18 | Summary: java.nio.file; Paths; true; get; ; ; Argument[0]; ReturnValue; taint; manual | +| 19 | Summary: java.nio.file; Paths; true; get; ; ; Argument[1].ArrayElement; ReturnValue; taint; manual | edges | Test.java:20:14:20:27 | (...)... : File | Test.java:21:19:21:20 | in : File | provenance | | | Test.java:20:20:20:27 | source(...) : Object | Test.java:20:14:20:27 | (...)... : File | provenance | | @@ -36,100 +35,96 @@ edges | Test.java:41:18:41:25 | source(...) : Object | Test.java:41:13:41:25 | (...)... : URI | provenance | | | Test.java:42:10:42:21 | new File(...) : File | Test.java:43:9:43:11 | out | provenance | | | Test.java:42:19:42:20 | in : URI | Test.java:42:10:42:21 | new File(...) : File | provenance | MaD:1 | -| Test.java:48:16:48:31 | (...)... : String | Test.java:49:31:49:32 | in : String | provenance | | +| Test.java:48:16:48:31 | (...)... : String | Test.java:50:9:50:11 | out | provenance | AdditionalTaintStep | | Test.java:48:24:48:31 | source(...) : Object | Test.java:48:16:48:31 | (...)... : String | provenance | | -| Test.java:49:10:49:33 | new File(...) : File | Test.java:50:9:50:11 | out | provenance | | -| Test.java:49:31:49:32 | in : String | Test.java:49:10:49:33 | new File(...) : File | provenance | MaD:2 | -| Test.java:55:16:55:31 | (...)... : String | Test.java:56:33:56:34 | in : String | provenance | | +| Test.java:55:16:55:31 | (...)... : String | Test.java:57:9:57:11 | out | provenance | AdditionalTaintStep | | Test.java:55:24:55:31 | source(...) : Object | Test.java:55:16:55:31 | (...)... : String | provenance | | -| Test.java:56:10:56:35 | new File(...) : File | Test.java:57:9:57:11 | out | provenance | | -| Test.java:56:33:56:34 | in : String | Test.java:56:10:56:35 | new File(...) : File | provenance | MaD:2 | | Test.java:62:14:62:27 | (...)... : File | Test.java:63:10:63:11 | in : File | provenance | | | Test.java:62:20:62:27 | source(...) : Object | Test.java:62:14:62:27 | (...)... : File | provenance | | -| Test.java:63:10:63:11 | in : File | Test.java:63:10:63:29 | getAbsoluteFile(...) : File | provenance | MaD:3 | +| Test.java:63:10:63:11 | in : File | Test.java:63:10:63:29 | getAbsoluteFile(...) : File | provenance | MaD:2 | | Test.java:63:10:63:29 | getAbsoluteFile(...) : File | Test.java:64:9:64:11 | out | provenance | | | Test.java:69:14:69:27 | (...)... : File | Test.java:70:10:70:11 | in : File | provenance | | | Test.java:69:20:69:27 | source(...) : Object | Test.java:69:14:69:27 | (...)... : File | provenance | | -| Test.java:70:10:70:11 | in : File | Test.java:70:10:70:29 | getAbsolutePath(...) : String | provenance | MaD:4 | +| Test.java:70:10:70:11 | in : File | Test.java:70:10:70:29 | getAbsolutePath(...) : String | provenance | MaD:3 | | Test.java:70:10:70:29 | getAbsolutePath(...) : String | Test.java:71:9:71:11 | out | provenance | | | Test.java:76:14:76:27 | (...)... : File | Test.java:77:10:77:11 | in : File | provenance | | | Test.java:76:20:76:27 | source(...) : Object | Test.java:76:14:76:27 | (...)... : File | provenance | | -| Test.java:77:10:77:11 | in : File | Test.java:77:10:77:30 | getCanonicalFile(...) : File | provenance | MaD:5 | +| Test.java:77:10:77:11 | in : File | Test.java:77:10:77:30 | getCanonicalFile(...) : File | provenance | MaD:4 | | Test.java:77:10:77:30 | getCanonicalFile(...) : File | Test.java:78:9:78:11 | out | provenance | | | Test.java:83:14:83:27 | (...)... : File | Test.java:84:10:84:11 | in : File | provenance | | | Test.java:83:20:83:27 | source(...) : Object | Test.java:83:14:83:27 | (...)... : File | provenance | | -| Test.java:84:10:84:11 | in : File | Test.java:84:10:84:30 | getCanonicalPath(...) : String | provenance | MaD:6 | +| Test.java:84:10:84:11 | in : File | Test.java:84:10:84:30 | getCanonicalPath(...) : String | provenance | MaD:5 | | Test.java:84:10:84:30 | getCanonicalPath(...) : String | Test.java:85:9:85:11 | out | provenance | | | Test.java:90:14:90:27 | (...)... : File | Test.java:91:10:91:11 | in : File | provenance | | | Test.java:90:20:90:27 | source(...) : Object | Test.java:90:14:90:27 | (...)... : File | provenance | | -| Test.java:91:10:91:11 | in : File | Test.java:91:10:91:20 | toPath(...) : Path | provenance | MaD:7 | +| Test.java:91:10:91:11 | in : File | Test.java:91:10:91:20 | toPath(...) : Path | provenance | MaD:6 | | Test.java:91:10:91:20 | toPath(...) : Path | Test.java:92:9:92:11 | out | provenance | | | Test.java:97:14:97:27 | (...)... : File | Test.java:98:10:98:11 | in : File | provenance | | | Test.java:97:20:97:27 | source(...) : Object | Test.java:97:14:97:27 | (...)... : File | provenance | | -| Test.java:98:10:98:11 | in : File | Test.java:98:10:98:22 | toString(...) : String | provenance | MaD:8 | +| Test.java:98:10:98:11 | in : File | Test.java:98:10:98:22 | toString(...) : String | provenance | MaD:7 | | Test.java:98:10:98:22 | toString(...) : String | Test.java:99:9:99:11 | out | provenance | | | Test.java:104:14:104:27 | (...)... : File | Test.java:105:10:105:11 | in : File | provenance | | | Test.java:104:20:104:27 | source(...) : Object | Test.java:104:14:104:27 | (...)... : File | provenance | | -| Test.java:105:10:105:11 | in : File | Test.java:105:10:105:19 | toURI(...) : URI | provenance | MaD:9 | +| Test.java:105:10:105:11 | in : File | Test.java:105:10:105:19 | toURI(...) : URI | provenance | MaD:8 | | Test.java:105:10:105:19 | toURI(...) : URI | Test.java:106:9:106:11 | out | provenance | | | Test.java:111:16:111:31 | (...)... : String | Test.java:113:27:113:28 | in : String | provenance | | | Test.java:111:24:111:31 | source(...) : Object | Test.java:111:16:111:31 | (...)... : String | provenance | | | Test.java:113:10:113:45 | getPath(...) : Path | Test.java:114:9:114:11 | out | provenance | | -| Test.java:113:27:113:28 | in : String | Test.java:113:10:113:45 | getPath(...) : Path | provenance | MaD:10 | +| Test.java:113:27:113:28 | in : String | Test.java:113:10:113:45 | getPath(...) : Path | provenance | MaD:9 | | Test.java:119:14:119:27 | (...)... : Path | Test.java:120:10:120:11 | in : Path | provenance | | | Test.java:119:20:119:27 | source(...) : Object | Test.java:119:14:119:27 | (...)... : Path | provenance | | -| Test.java:120:10:120:11 | in : Path | Test.java:120:10:120:20 | toFile(...) : File | provenance | MaD:11 | +| Test.java:120:10:120:11 | in : Path | Test.java:120:10:120:20 | toFile(...) : File | provenance | MaD:10 | | Test.java:120:10:120:20 | toFile(...) : File | Test.java:121:9:121:11 | out | provenance | | | Test.java:126:14:126:27 | (...)... : Path | Test.java:127:10:127:11 | in : Path | provenance | | | Test.java:126:20:126:27 | source(...) : Object | Test.java:126:14:126:27 | (...)... : Path | provenance | | -| Test.java:127:10:127:11 | in : Path | Test.java:127:10:127:23 | getParent(...) : Path | provenance | MaD:12 | +| Test.java:127:10:127:11 | in : Path | Test.java:127:10:127:23 | getParent(...) : Path | provenance | MaD:11 | | Test.java:127:10:127:23 | getParent(...) : Path | Test.java:128:9:128:11 | out | provenance | | | Test.java:133:14:133:27 | (...)... : Path | Test.java:134:10:134:11 | in : Path | provenance | | | Test.java:133:20:133:27 | source(...) : Object | Test.java:133:14:133:27 | (...)... : Path | provenance | | -| Test.java:134:10:134:11 | in : Path | Test.java:134:10:134:23 | normalize(...) : Path | provenance | MaD:13 | +| Test.java:134:10:134:11 | in : Path | Test.java:134:10:134:23 | normalize(...) : Path | provenance | MaD:12 | | Test.java:134:10:134:23 | normalize(...) : Path | Test.java:135:9:135:11 | out | provenance | | | Test.java:140:14:140:27 | (...)... : Path | Test.java:142:27:142:28 | in : Path | provenance | | | Test.java:140:20:140:27 | source(...) : Object | Test.java:140:14:140:27 | (...)... : Path | provenance | | | Test.java:142:10:142:29 | resolve(...) : Path | Test.java:143:9:143:11 | out | provenance | | -| Test.java:142:27:142:28 | in : Path | Test.java:142:10:142:29 | resolve(...) : Path | provenance | MaD:14 | +| Test.java:142:27:142:28 | in : Path | Test.java:142:10:142:29 | resolve(...) : Path | provenance | MaD:13 | | Test.java:148:14:148:27 | (...)... : Path | Test.java:149:10:149:11 | in : Path | provenance | | | Test.java:148:20:148:27 | source(...) : Object | Test.java:148:14:148:27 | (...)... : Path | provenance | | -| Test.java:149:10:149:11 | in : Path | Test.java:149:10:149:31 | resolve(...) : Path | provenance | MaD:15 | +| Test.java:149:10:149:11 | in : Path | Test.java:149:10:149:31 | resolve(...) : Path | provenance | MaD:14 | | Test.java:149:10:149:31 | resolve(...) : Path | Test.java:150:9:150:11 | out | provenance | | | Test.java:155:14:155:27 | (...)... : Path | Test.java:156:10:156:11 | in : Path | provenance | | | Test.java:155:20:155:27 | source(...) : Object | Test.java:155:14:155:27 | (...)... : Path | provenance | | -| Test.java:156:10:156:11 | in : Path | Test.java:156:10:156:33 | resolve(...) : Path | provenance | MaD:15 | +| Test.java:156:10:156:11 | in : Path | Test.java:156:10:156:33 | resolve(...) : Path | provenance | MaD:14 | | Test.java:156:10:156:33 | resolve(...) : Path | Test.java:157:9:157:11 | out | provenance | | | Test.java:162:16:162:31 | (...)... : String | Test.java:164:27:164:28 | in : String | provenance | | | Test.java:162:24:162:31 | source(...) : Object | Test.java:162:16:162:31 | (...)... : String | provenance | | | Test.java:164:10:164:29 | resolve(...) : Path | Test.java:165:9:165:11 | out | provenance | | -| Test.java:164:27:164:28 | in : String | Test.java:164:10:164:29 | resolve(...) : Path | provenance | MaD:14 | +| Test.java:164:27:164:28 | in : String | Test.java:164:10:164:29 | resolve(...) : Path | provenance | MaD:13 | | Test.java:170:14:170:27 | (...)... : Path | Test.java:171:10:171:11 | in : Path | provenance | | | Test.java:170:20:170:27 | source(...) : Object | Test.java:170:14:170:27 | (...)... : Path | provenance | | -| Test.java:171:10:171:11 | in : Path | Test.java:171:10:171:28 | toAbsolutePath(...) : Path | provenance | MaD:16 | +| Test.java:171:10:171:11 | in : Path | Test.java:171:10:171:28 | toAbsolutePath(...) : Path | provenance | MaD:15 | | Test.java:171:10:171:28 | toAbsolutePath(...) : Path | Test.java:172:9:172:11 | out | provenance | | | Test.java:177:14:177:27 | (...)... : Path | Test.java:178:10:178:11 | in : Path | provenance | | | Test.java:177:20:177:27 | source(...) : Object | Test.java:177:14:177:27 | (...)... : Path | provenance | | -| Test.java:178:10:178:11 | in : Path | Test.java:178:10:178:22 | toString(...) : String | provenance | MaD:17 | +| Test.java:178:10:178:11 | in : Path | Test.java:178:10:178:22 | toString(...) : String | provenance | MaD:16 | | Test.java:178:10:178:22 | toString(...) : String | Test.java:179:9:179:11 | out | provenance | | | Test.java:184:14:184:27 | (...)... : Path | Test.java:185:10:185:11 | in : Path | provenance | | | Test.java:184:20:184:27 | source(...) : Object | Test.java:184:14:184:27 | (...)... : Path | provenance | | -| Test.java:185:10:185:11 | in : Path | Test.java:185:10:185:19 | toUri(...) : URI | provenance | MaD:18 | +| Test.java:185:10:185:11 | in : Path | Test.java:185:10:185:19 | toUri(...) : URI | provenance | MaD:17 | | Test.java:185:10:185:19 | toUri(...) : URI | Test.java:186:9:186:11 | out | provenance | | | Test.java:191:16:191:31 | (...)... : String | Test.java:192:20:192:21 | in : String | provenance | | | Test.java:191:24:191:31 | source(...) : Object | Test.java:191:16:191:31 | (...)... : String | provenance | | | Test.java:192:10:192:38 | get(...) : Path | Test.java:193:9:193:11 | out | provenance | | -| Test.java:192:20:192:21 | in : String | Test.java:192:10:192:38 | get(...) : Path | provenance | MaD:19 | +| Test.java:192:20:192:21 | in : String | Test.java:192:10:192:38 | get(...) : Path | provenance | MaD:18 | | Test.java:198:13:198:25 | (...)... : URI | Test.java:199:20:199:21 | in : URI | provenance | | | Test.java:198:18:198:25 | source(...) : Object | Test.java:198:13:198:25 | (...)... : URI | provenance | | | Test.java:199:10:199:22 | get(...) : Path | Test.java:200:9:200:11 | out | provenance | | -| Test.java:199:20:199:21 | in : URI | Test.java:199:10:199:22 | get(...) : Path | provenance | MaD:19 | +| Test.java:199:20:199:21 | in : URI | Test.java:199:10:199:22 | get(...) : Path | provenance | MaD:18 | | Test.java:205:18:205:57 | (...)... : String[] [[]] : String | Test.java:206:34:206:35 | in : String[] [[]] : String | provenance | | | Test.java:205:28:205:57 | {...} : String[] [[]] : String | Test.java:205:18:205:57 | (...)... : String[] [[]] : String | provenance | | | Test.java:205:41:205:56 | (...)... : String | Test.java:205:28:205:57 | {...} : String[] [[]] : String | provenance | | | Test.java:205:49:205:56 | source(...) : Object | Test.java:205:41:205:56 | (...)... : String | provenance | | | Test.java:206:10:206:36 | get(...) : Path | Test.java:207:9:207:11 | out | provenance | | -| Test.java:206:34:206:35 | in : String[] [[]] : String | Test.java:206:10:206:36 | get(...) : Path | provenance | MaD:20 | +| Test.java:206:34:206:35 | in : String[] [[]] : String | Test.java:206:10:206:36 | get(...) : Path | provenance | MaD:19 | nodes | Test.java:20:14:20:27 | (...)... : File | semmle.label | (...)... : File | | Test.java:20:20:20:27 | source(...) : Object | semmle.label | source(...) : Object | @@ -153,13 +148,9 @@ nodes | Test.java:43:9:43:11 | out | semmle.label | out | | Test.java:48:16:48:31 | (...)... : String | semmle.label | (...)... : String | | Test.java:48:24:48:31 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:49:10:49:33 | new File(...) : File | semmle.label | new File(...) : File | -| Test.java:49:31:49:32 | in : String | semmle.label | in : String | | Test.java:50:9:50:11 | out | semmle.label | out | | Test.java:55:16:55:31 | (...)... : String | semmle.label | (...)... : String | | Test.java:55:24:55:31 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:56:10:56:35 | new File(...) : File | semmle.label | new File(...) : File | -| Test.java:56:33:56:34 | in : String | semmle.label | in : String | | Test.java:57:9:57:11 | out | semmle.label | out | | Test.java:62:14:62:27 | (...)... : File | semmle.label | (...)... : File | | Test.java:62:20:62:27 | source(...) : Object | semmle.label | source(...) : Object | diff --git a/java/ql/test/library-tests/pathsanitizer/Test.java b/java/ql/test/library-tests/pathsanitizer/Test.java index 718d31dcda6b..d3285352fa38 100644 --- a/java/ql/test/library-tests/pathsanitizer/Test.java +++ b/java/ql/test/library-tests/pathsanitizer/Test.java @@ -463,4 +463,145 @@ public void blockListGuard() throws Exception { } } } + + private void fileConstructorValidation(String path) throws Exception { + // Use `indexOf` instead of `contains` for this test since a `contains` + // call in this scenario will already be sanitized due to the inclusion + // of `ValidatedVariableAccess` nodes in `defaultTaintSanitizer`. + if (path.indexOf("..") != -1) + throw new Exception(); + } + + public void fileConstructorSanitizer() throws Exception { + // PathTraversalGuard + { + String source = (String) source(); + File f1 = new File("safe/file.txt"); + if (!source.contains("..")) { + File f2 = new File(f1, source); + sink(f2); // Safe + sink(source); // $ hasTaintFlow + } else { + File f3 = new File(f1, source); + sink(f3); // $ hasTaintFlow + sink(source); // $ hasTaintFlow + } + } + { + String source = (String) source(); + File f1Tainted = (File) source(); + if (!source.contains("..")) { + // `f2` is unsafe if `f1` is tainted + File f2 = new File(f1Tainted, source); + sink(f2); // $ hasTaintFlow + sink(source); // $ hasTaintFlow + } else { + File f3 = new File(f1Tainted, source); + sink(f3); // $ hasTaintFlow + sink(source); // $ hasTaintFlow + } + } + { + String source = (String) source(); + File f1Null = null; + if (!source.contains("..")) { + // `f2` is unsafe if `f1` is null + File f2 = new File(f1Null, source); + sink(f2); // $ hasTaintFlow + sink(source); // $ hasTaintFlow + } else { + File f3 = new File(f1Null, source); + sink(f3); // $ hasTaintFlow + sink(source); // $ hasTaintFlow + } + } + { + String source = (String) source(); + File f1 = new File("safe/file.txt"); + if (source.indexOf("..") == -1) { + File f2 = new File(f1, source); + sink(f2); // Safe + sink(source); // $ hasTaintFlow + } else { + File f3 = new File(f1, source); + sink(f3); // $ hasTaintFlow + sink(source); // $ hasTaintFlow + } + } + { + String source = (String) source(); + File f1 = new File("safe/file.txt"); + if (source.indexOf("..") != -1) { + File f2 = new File(f1, source); + sink(f2); // $ hasTaintFlow + sink(source); // $ hasTaintFlow + } else { + File f3 = new File(f1, source); + sink(f3); // Safe + sink(source); // $ hasTaintFlow + } + } + { + String source = (String) source(); + File f1 = new File("safe/file.txt"); + if (source.lastIndexOf("..") == -1) { + File f2 = new File(f1, source); + sink(f2); // Safe + sink(source); // $ hasTaintFlow + } else { + File f3 = new File(f1, source); + sink(f3); // $ hasTaintFlow + sink(source); // $ hasTaintFlow + } + } + // validation method + { + String source = (String) source(); + File f1 = new File("safe/file.txt"); + fileConstructorValidation(source); + File f2 = new File(f1, source); + sink(f2); // Safe + sink(source); // $ hasTaintFlow + } + { + String source = (String) source(); + File f1 = new File("safe/file.txt"); + + if (source.contains("..")) { + throw new Exception(); + } else { + File f2 = new File(f1, source); + sink(f2); // Safe + sink(source); // $ hasTaintFlow + } + } + // PathNormalizeSanitizer + { + File source = (File) source(); + String normalized = source.getCanonicalPath(); + File f1 = new File("safe/file.txt"); + File f2 = new File(f1, normalized); + sink(f2); // Safe + sink(source); // $ hasTaintFlow + sink(normalized); // $ hasTaintFlow + } + { + File source = (File) source(); + String normalized = source.getCanonicalFile().toString(); + File f1 = new File("safe/file.txt"); + File f2 = new File(f1, normalized); + sink(f2); // Safe + sink(source); // $ hasTaintFlow + sink(normalized); // $ hasTaintFlow + } + { + String source = (String) source(); + String normalized = Paths.get(source).normalize().toString(); + File f1 = new File("safe/file.txt"); + File f2 = new File(f1, normalized); + sink(f2); // Safe + sink(source); // $ hasTaintFlow + sink(normalized); // $ hasTaintFlow + } + } } diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipSlip.expected b/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipSlip.expected index b4880e1d511e..0d081a456e8e 100644 --- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipSlip.expected +++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipSlip.expected @@ -3,20 +3,15 @@ | ZipTest.java:7:19:7:33 | getName(...) | ZipTest.java:7:19:7:33 | getName(...) : String | ZipTest.java:10:49:10:52 | file | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipTest.java:10:49:10:52 | file | file system operation | | ZipTest.java:7:19:7:33 | getName(...) | ZipTest.java:7:19:7:33 | getName(...) : String | ZipTest.java:11:36:11:39 | file | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipTest.java:11:36:11:39 | file | file system operation | edges -| ZipTest.java:7:19:7:33 | getName(...) : String | ZipTest.java:8:31:8:34 | name : String | provenance | | -| ZipTest.java:8:17:8:35 | new File(...) : File | ZipTest.java:9:48:9:51 | file | provenance | Sink:MaD:1 | -| ZipTest.java:8:17:8:35 | new File(...) : File | ZipTest.java:10:49:10:52 | file | provenance | Sink:MaD:3 | -| ZipTest.java:8:17:8:35 | new File(...) : File | ZipTest.java:11:36:11:39 | file | provenance | Sink:MaD:2 | -| ZipTest.java:8:31:8:34 | name : String | ZipTest.java:8:17:8:35 | new File(...) : File | provenance | MaD:4 | +| ZipTest.java:7:19:7:33 | getName(...) : String | ZipTest.java:9:48:9:51 | file | provenance | AdditionalTaintStep Sink:MaD:1 | +| ZipTest.java:7:19:7:33 | getName(...) : String | ZipTest.java:10:49:10:52 | file | provenance | AdditionalTaintStep Sink:MaD:3 | +| ZipTest.java:7:19:7:33 | getName(...) : String | ZipTest.java:11:36:11:39 | file | provenance | AdditionalTaintStep Sink:MaD:2 | models | 1 | Sink: java.io; FileOutputStream; false; FileOutputStream; ; ; Argument[0]; path-injection; manual | | 2 | Sink: java.io; FileWriter; false; FileWriter; ; ; Argument[0]; path-injection; manual | | 3 | Sink: java.io; RandomAccessFile; false; RandomAccessFile; ; ; Argument[0]; path-injection; manual | -| 4 | Summary: java.io; File; false; File; ; ; Argument[1]; Argument[this]; taint; manual | nodes | ZipTest.java:7:19:7:33 | getName(...) : String | semmle.label | getName(...) : String | -| ZipTest.java:8:17:8:35 | new File(...) : File | semmle.label | new File(...) : File | -| ZipTest.java:8:31:8:34 | name : String | semmle.label | name : String | | ZipTest.java:9:48:9:51 | file | semmle.label | file | | ZipTest.java:10:49:10:52 | file | semmle.label | file | | ZipTest.java:11:36:11:39 | file | semmle.label | file |