diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll index e9c457fc801..3acb3291911 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -244,8 +244,14 @@ private class ContainerFlowSummaries extends SummaryModelCsv { "java.util;Properties;true;getProperty;(String);;Argument[-1].MapValue;ReturnValue;value;manual", "java.util;Properties;true;getProperty;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual", "java.util;Properties;true;getProperty;(String,String);;Argument[1];ReturnValue;value;manual", + "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual", "java.util;Scanner;true;next;(Pattern);;Argument[-1];ReturnValue;taint;manual", "java.util;Scanner;true;next;(String);;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;reset;;;Argument[-1];ReturnValue;value;manual", + "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual", + "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual", + "java.util;Scanner;true;useLocale;;;Argument[-1];ReturnValue;value;manual", + "java.util;Scanner;true;useRadix;;;Argument[-1];ReturnValue;value;manual", "java.util;SortedMap;true;headMap;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", "java.util;SortedMap;true;headMap;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", "java.util;SortedMap;true;subMap;(Object,Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", diff --git a/java/ql/test/library-tests/scanner/Test.java b/java/ql/test/library-tests/scanner/Test.java new file mode 100644 index 00000000000..d5bd778fe1b --- /dev/null +++ b/java/ql/test/library-tests/scanner/Test.java @@ -0,0 +1,183 @@ +package generatedtest; + +import java.io.File; +import java.io.InputStream; +import java.nio.channels.ReadableByteChannel; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.util.Scanner; +import java.util.regex.Pattern; + +// Test case generated by GenerateFlowTestCase.ql +public class Test { + + Object source() { return null; } + void sink(Object o) { } + + public void test() throws Exception { + + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + File in = (File)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + File in = (File)source(); + out = new Scanner(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + File in = (File)source(); + out = new Scanner(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + InputStream in = (InputStream)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + InputStream in = (InputStream)source(); + out = new Scanner(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + InputStream in = (InputStream)source(); + out = new Scanner(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Path in = (Path)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Path in = (Path)source(); + out = new Scanner(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Path in = (Path)source(); + out = new Scanner(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Readable in = (Readable)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + ReadableByteChannel in = (ReadableByteChannel)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + ReadableByteChannel in = (ReadableByteChannel)source(); + out = new Scanner(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + ReadableByteChannel in = (ReadableByteChannel)source(); + out = new Scanner(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + String in = (String)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;next;(Pattern);;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner)source(); + out = in.next((Pattern)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;next;(String);;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner)source(); + out = in.next((String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;reset;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.reset(); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.skip((Pattern)null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.skip((String)null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.useDelimiter((Pattern)null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.useDelimiter((String)null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useLocale;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.useLocale(null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useRadix;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.useRadix(0); + sink(out); // $ hasValueFlow + } + + } + +} \ No newline at end of file diff --git a/java/ql/test/library-tests/scanner/test.expected b/java/ql/test/library-tests/scanner/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/scanner/test.ql b/java/ql/test/library-tests/scanner/test.ql new file mode 100644 index 00000000000..5d91e4e8e26 --- /dev/null +++ b/java/ql/test/library-tests/scanner/test.ql @@ -0,0 +1,2 @@ +import java +import TestUtilities.InlineFlowTest