diff --git a/java/ql/src/semmle/code/java/frameworks/guava/Base.qll b/java/ql/src/semmle/code/java/frameworks/guava/Base.qll index 01e90e7b0a7..174d8d19f33 100644 --- a/java/ql/src/semmle/code/java/frameworks/guava/Base.qll +++ b/java/ql/src/semmle/code/java/frameworks/guava/Base.qll @@ -50,7 +50,7 @@ private class GuavaBaseCsv extends SummaryModelCsv { "com.google.common.base;Ascii;false;toUpperCase;(String);;Argument[0];ReturnValue;taint", "com.google.common.base;Ascii;false;truncate;(CharSequence,int,String);;Argument[0];ReturnValue;taint", "com.google.common.base;Ascii;false;truncate;(CharSequence,int,String);;Argument[2];ReturnValue;taint", - "com.google.common.base;CaseFormat;true;to;(CharFormat,String);;Argument[1];ReturnValue;taint", + "com.google.common.base;CaseFormat;true;to;(CaseFormat,String);;Argument[1];ReturnValue;taint", "com.google.common.base;Converter;true;apply;;;Argument[0];ReturnValue;taint", "com.google.common.base;Converter;true;convert;;;Argument[0];ReturnValue;taint", "com.google.common.base;Converter;true;convertAll;;;Argument[0];ReturnValue;taint", @@ -65,6 +65,8 @@ private class GuavaBaseCsv extends SummaryModelCsv { "com.google.common.base;Optional;true;asSet;();;Argument[-1];ReturnValue;taint", "com.google.common.base;Optional;true;of;(T);;Argument[0];ReturnValue;taint", "com.google.common.base;Optional;true;or;;;Argument[-1];ReturnValue;taint", + "com.google.common.base;Optional;true;or;;;Argument[0];ReturnValue;taint", + "com.google.common.base;Optional;true;orNull;();;Argument[-1];ReturnValue;taint", "com.google.common.base;Optional;true;presentInstances;;;Argument[0];ReturnValue;taint", "com.google.common.base;Optional;true;toJavaUtil;();;Argument[-1];ReturnValue;taint", "com.google.common.base;Optional;true;toJavaUtil;(Optional);;Argument[0];ReturnValue;taint", diff --git a/java/ql/test/library-tests/frameworks/guava/TestBase.java b/java/ql/test/library-tests/frameworks/guava/TestBase.java index 8da63965d58..c91bd06c4f8 100644 --- a/java/ql/test/library-tests/frameworks/guava/TestBase.java +++ b/java/ql/test/library-tests/frameworks/guava/TestBase.java @@ -2,6 +2,7 @@ package com.google.common.base; import java.util.Map; import java.util.HashMap; +import java.util.concurrent.TimeUnit; class TestBase { String taint() { return "tainted"; } @@ -59,6 +60,50 @@ class TestBase { void test4() { sink(Preconditions.checkNotNull(taint())); // $numTaintFlow=1 + sink(Verify.verifyNotNull(taint())); // $numTaintFlow=1 + } + + void test5() { + sink(Ascii.toLowerCase(taint())); // $numTaintFlow=1 + sink(Ascii.toUpperCase(taint())); // $numTaintFlow=1 + sink(Ascii.truncate(taint(), 3, "...")); // $numTaintFlow=1 + sink(Ascii.truncate("abcabcabc", 3, taint())); // $numTaintFlow=1 + sink(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, taint())); // $numTaintFlow=1 + sink(CaseFormat.LOWER_HYPHEN.converterTo(CaseFormat.UPPER_CAMEL).convert(taint())); // $numTaintFlow=1 + sink(CaseFormat.LOWER_UNDERSCORE.converterTo(CaseFormat.LOWER_HYPHEN).reverse().convert(taint())); // $numTaintFlow=1 + } + + void test6() { + sink(Suppliers.memoize(Suppliers.memoizeWithExpiration(Suppliers.synchronizedSupplier(Suppliers.ofInstance(taint())), 3, TimeUnit.HOURS))); // $numTaintFlow=1 + } + + void test7() { + sink(MoreObjects.firstNonNull(taint(), "abc")); // $numTaintFlow=1 + sink(MoreObjects.firstNonNull(null, taint())); // $numTaintFlow=1 + sink(MoreObjects.toStringHelper(taint()).add("x", 3).omitNullValues().toString()); // $numTaintFlow=1 + sink(MoreObjects.toStringHelper((Object) taint()).toString()); + sink(MoreObjects.toStringHelper("a").add("x", 3).add(taint(), 4).toString()); // $numTaintFlow=1 + sink(MoreObjects.toStringHelper("a").add("x", taint()).toString()); // $numTaintFlow=1 + sink(MoreObjects.toStringHelper("a").addValue(taint()).toString()); // $numTaintFlow=1 + MoreObjects.ToStringHelper h = MoreObjects.toStringHelper("a"); + h.add("x", 3).add(taint(), 4); + sink(h.add("z",5).toString()); // $numTaintFlow=1 + } + + void test8() { + Optional x = Optional.of(taint()); + sink(x); // $numTaintFlow=1 + sink(x.get()); // $numTaintFlow=1 + sink(x.or("hi")); // $numTaintFlow=1 + sink(x.orNull()); // $numTaintFlow=1 + sink(x.asSet()); // $numTaintFlow=1 + sink(Optional.fromJavaUtil(x.toJavaUtil())); // $numTaintFlow=1 + sink(Optional.fromJavaUtil(Optional.toJavaUtil(x))); // $numTaintFlow=1 + sink(x.asSet()); // $numTaintFlow=1 + sink(Optional.fromNullable(taint())); // $numTaintFlow=1 + sink(Optional.absent().or(x)); // $numTaintFlow=1 + sink(Optional.absent().or(taint())); // $numTaintFlow=1 + sink(Optional.presentInstances(Optional.of(x).asSet())); // $numTaintFlow=1 } void test5() { diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/Ascii.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/Ascii.java new file mode 100644 index 00000000000..f5feafe474f --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/Ascii.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.base; + +public final class Ascii { + public static String toLowerCase(String string) { + return null; + } + + public static String toLowerCase(CharSequence chars) { + return null; + } + + public static char toLowerCase(char c) { + return '0'; + } + + public static String toUpperCase(String string) { + return null; + } + + public static String toUpperCase(CharSequence chars) { + return null; + } + + public static char toUpperCase(char c) { + return '0'; + } + + public static boolean isLowerCase(char c) { + return false; + } + + public static boolean isUpperCase(char c) { + return false; + } + + public static String truncate(CharSequence seq, int maxLength, String truncationIndicator) { + return null; + } + + public static boolean equalsIgnoreCase(CharSequence s1, CharSequence s2) { + return false; + } + +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/CaseFormat.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/CaseFormat.java new file mode 100644 index 00000000000..4d0df360197 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/CaseFormat.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2006 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.base; + +public enum CaseFormat { + LOWER_HYPHEN, + LOWER_UNDERSCORE, + LOWER_CAMEL, + UPPER_CAMEL, + UPPER_UNDERSCORE; + + public final String to(CaseFormat format, String str) { + return null; + } + + public Converter converterTo(CaseFormat targetFormat) { + return null; + } + +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/Converter.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/Converter.java new file mode 100644 index 00000000000..d4e59f3ff91 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/Converter.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.base; +import org.checkerframework.checker.nullness.qual.Nullable; + +public abstract class Converter implements Function { + public final @Nullable B convert(@Nullable A a) { + return null; + } + + public Iterable convertAll(final Iterable fromIterable) { + return null; + } + + public Converter reverse() { + return null; + } + + public final Converter andThen(Converter secondConverter) { + return null; + } + + @Override + public final @Nullable B apply(@Nullable A a) { + return null; + } + + @Override + public boolean equals(@Nullable Object object) { + return false; + } + + public static Converter from( + Function forwardFunction, + Function backwardFunction) { + return null; + } + + public static Converter identity() { + return null; + } + +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/MoreObjects.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/MoreObjects.java index 3f4912b021b..31e3638adec 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/base/MoreObjects.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/MoreObjects.java @@ -1,9 +1,102 @@ -package com.google.common.base; +/* + * Copyright (C) 2014 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.common.base; import org.checkerframework.checker.nullness.qual.Nullable; public final class MoreObjects { - public static T firstNonNull(@Nullable T first, @Nullable T second) { - return null; + public static T firstNonNull(@Nullable T first, @Nullable T second) { + return null; + } + + public static ToStringHelper toStringHelper(Object self) { + return null; + } + + public static ToStringHelper toStringHelper(Class clazz) { + return null; + } + + public static ToStringHelper toStringHelper(String className) { + return null; + } + + public static final class ToStringHelper { + public ToStringHelper omitNullValues() { + return null; } -} \ No newline at end of file + + public ToStringHelper add(String name, @Nullable Object value) { + return null; + } + + public ToStringHelper add(String name, boolean value) { + return null; + } + + public ToStringHelper add(String name, char value) { + return null; + } + + public ToStringHelper add(String name, double value) { + return null; + } + + public ToStringHelper add(String name, float value) { + return null; + } + + public ToStringHelper add(String name, int value) { + return null; + } + + public ToStringHelper add(String name, long value) { + return null; + } + + public ToStringHelper addValue(@Nullable Object value) { + return null; + } + + public ToStringHelper addValue(boolean value) { + return null; + } + + public ToStringHelper addValue(char value) { + return null; + } + + public ToStringHelper addValue(double value) { + return null; + } + + public ToStringHelper addValue(float value) { + return null; + } + + public ToStringHelper addValue(int value) { + return null; + } + + public ToStringHelper addValue(long value) { + return null; + } + + @Override + public String toString() { + return null; + } + + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/Optional.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/Optional.java index f6f757ac994..3f39995651a 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/base/Optional.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/Optional.java @@ -31,11 +31,11 @@ public abstract class Optional implements Serializable { } public static @Nullable Optional fromJavaUtil( - java.util.Optional javaUtilOptional) { + java.util.@Nullable Optional javaUtilOptional) { return null; } - public static java.util.Optional toJavaUtil( + public static java.util.@Nullable Optional toJavaUtil( @Nullable Optional googleOptional) { return null; } diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/Suppliers.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/Suppliers.java new file mode 100644 index 00000000000..5e5b2d47820 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/Suppliers.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.base; +import java.util.concurrent.TimeUnit; +import org.checkerframework.checker.nullness.qual.Nullable; + +public final class Suppliers { + public static Supplier compose(Function function, Supplier supplier) { + return null; + } + + public static Supplier memoize(Supplier delegate) { + return null; + } + + public static Supplier memoizeWithExpiration( + Supplier delegate, long duration, TimeUnit unit) { + return null; + } + + public static Supplier ofInstance(@Nullable T instance) { + return null; + } + + public static Supplier synchronizedSupplier(Supplier delegate) { + return null; + } + + public static Function, T> supplierFunction() { + return null; + } + +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/Verify.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/Verify.java new file mode 100644 index 00000000000..8016ec83489 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/Verify.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.base; +import org.checkerframework.checker.nullness.qual.Nullable; + +public final class Verify { + public static void verify(boolean expression) { + } + + public static void verify( + boolean expression, + @Nullable String errorMessageTemplate, + @Nullable Object @Nullable ... errorMessageArgs) { + } + + public static void verify(boolean expression, @Nullable String errorMessageTemplate, char p1) { + } + + public static void verify(boolean expression, @Nullable String errorMessageTemplate, int p1) { + } + + public static void verify(boolean expression, @Nullable String errorMessageTemplate, long p1) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, @Nullable Object p1) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, char p1, char p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, int p1, char p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, long p1, char p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, @Nullable Object p1, char p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, char p1, int p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, int p1, int p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, long p1, int p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, @Nullable Object p1, int p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, char p1, long p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, int p1, long p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, long p1, long p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, @Nullable Object p1, long p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, char p1, @Nullable Object p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, int p1, @Nullable Object p2) { + } + + public static void verify( + boolean expression, @Nullable String errorMessageTemplate, long p1, @Nullable Object p2) { + } + + public static void verify( + boolean expression, + @Nullable String errorMessageTemplate, + @Nullable Object p1, + @Nullable Object p2) { + } + + public static void verify( + boolean expression, + @Nullable String errorMessageTemplate, + @Nullable Object p1, + @Nullable Object p2, + @Nullable Object p3) { + } + + public static void verify( + boolean expression, + @Nullable String errorMessageTemplate, + @Nullable Object p1, + @Nullable Object p2, + @Nullable Object p3, + @Nullable Object p4) { + } + + public static T verifyNotNull(@Nullable T reference) { + return null; + } + + public static T verifyNotNull( + @Nullable T reference, + @Nullable String errorMessageTemplate, + @Nullable Object @Nullable ... errorMessageArgs) { + return null; + } + +}