Loading errorprone/java/com/google/errorprone/bugpatterns/android/UidChecker.java +15 −3 Original line number Diff line number Diff line Loading @@ -23,12 +23,15 @@ import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.NewClassTreeMatcher; import com.google.errorprone.matchers.Description; import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.IdentifierTree; import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.NewClassTree; import com.sun.source.tree.Tree; import com.sun.tools.javac.code.Symbol.VarSymbol; import java.util.List; Loading @@ -44,11 +47,20 @@ import java.util.regex.Pattern; name = "AndroidFrameworkUid", summary = "Verifies that PID, UID and user ID arguments aren't crossed", severity = WARNING) public final class UidChecker extends BugChecker implements MethodInvocationTreeMatcher { public final class UidChecker extends BugChecker implements MethodInvocationTreeMatcher, NewClassTreeMatcher { @Override public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { final List<VarSymbol> vars = ASTHelpers.getSymbol(tree).params(); final List<? extends ExpressionTree> args = tree.getArguments(); return matchArguments(ASTHelpers.getSymbol(tree).params(), tree.getArguments(), tree); } @Override public Description matchNewClass(NewClassTree tree, VisitorState state) { return matchArguments(ASTHelpers.getSymbol(tree).params(), tree.getArguments(), tree); } private Description matchArguments(List<VarSymbol> vars, List<? extends ExpressionTree> args, Tree tree) { for (int i = 0; i < Math.min(vars.size(), args.size()); i++) { final Flavor varFlavor = getFlavor(vars.get(i)); final Flavor argFlavor = getFlavor(args.get(i)); Loading errorprone/tests/java/com/google/errorprone/bugpatterns/android/UidCheckerTest.java +69 −2 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ public class UidCheckerTest { } @Test public void testTypical() { public void testTypical_methodInvocation() { compilationHelper .addSourceLines("Example.java", "public abstract class Example {", Loading @@ -57,7 +57,30 @@ public class UidCheckerTest { } @Test public void testCallingUid() { public void testTypical_newClass() { compilationHelper .addSourceLines("Example.java", "public abstract class Example {", " class Bar { Bar(int pid, int uid, int userId) {} }", " abstract int getUserId();", " void foo(int pid, int uid, int userId, int unrelated) {", " new Bar(0, 0, 0);", " new Bar(pid, uid, userId);", " new Bar(pid, uid, getUserId());", " new Bar(unrelated, unrelated, unrelated);", " // BUG: Diagnostic contains:", " new Bar(uid, pid, userId);", " // BUG: Diagnostic contains:", " new Bar(pid, userId, uid);", " // BUG: Diagnostic contains:", " new Bar(getUserId(), 0, 0);", " }", "}") .doTest(); } @Test public void testCallingUid_methodInvocation() { compilationHelper .addSourceFile("/android/os/Binder.java") .addSourceFile("/android/os/UserHandle.java") Loading Loading @@ -98,4 +121,48 @@ public class UidCheckerTest { "}") .doTest(); } @Test public void testCallingUid_newClass() { compilationHelper .addSourceFile("/android/os/Binder.java") .addSourceFile("/android/os/UserHandle.java") .addSourceLines("Example.java", "import android.os.Binder;", "import android.os.UserHandle;", "public abstract class Example {", " int callingUserId;", " int callingUid;", " class Foo { Foo(int callingUserId) {} }", " class Bar { Bar(int callingUid) {} }", " void doUserId(int callingUserId) {", " new Foo(UserHandle.getUserId(Binder.getCallingUid()));", " new Foo(this.callingUserId);", " new Foo(callingUserId);", " // BUG: Diagnostic contains:", " new Foo(Binder.getCallingUid());", " // BUG: Diagnostic contains:", " new Foo(this.callingUid);", " // BUG: Diagnostic contains:", " new Foo(callingUid);", " }", " void doUid(int callingUserId) {", " new Bar(Binder.getCallingUid());", " new Bar(this.callingUid);", " new Bar(callingUid);", " // BUG: Diagnostic contains:", " new Bar(UserHandle.getUserId(Binder.getCallingUid()));", " // BUG: Diagnostic contains:", " new Bar(this.callingUserId);", " // BUG: Diagnostic contains:", " new Bar(callingUserId);", " }", " void doInner() {", " // BUG: Diagnostic contains:", " new Foo(UserHandle.getUserId(callingUserId));", " }", "}") .doTest(); } } Loading
errorprone/java/com/google/errorprone/bugpatterns/android/UidChecker.java +15 −3 Original line number Diff line number Diff line Loading @@ -23,12 +23,15 @@ import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.NewClassTreeMatcher; import com.google.errorprone.matchers.Description; import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.IdentifierTree; import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.NewClassTree; import com.sun.source.tree.Tree; import com.sun.tools.javac.code.Symbol.VarSymbol; import java.util.List; Loading @@ -44,11 +47,20 @@ import java.util.regex.Pattern; name = "AndroidFrameworkUid", summary = "Verifies that PID, UID and user ID arguments aren't crossed", severity = WARNING) public final class UidChecker extends BugChecker implements MethodInvocationTreeMatcher { public final class UidChecker extends BugChecker implements MethodInvocationTreeMatcher, NewClassTreeMatcher { @Override public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { final List<VarSymbol> vars = ASTHelpers.getSymbol(tree).params(); final List<? extends ExpressionTree> args = tree.getArguments(); return matchArguments(ASTHelpers.getSymbol(tree).params(), tree.getArguments(), tree); } @Override public Description matchNewClass(NewClassTree tree, VisitorState state) { return matchArguments(ASTHelpers.getSymbol(tree).params(), tree.getArguments(), tree); } private Description matchArguments(List<VarSymbol> vars, List<? extends ExpressionTree> args, Tree tree) { for (int i = 0; i < Math.min(vars.size(), args.size()); i++) { final Flavor varFlavor = getFlavor(vars.get(i)); final Flavor argFlavor = getFlavor(args.get(i)); Loading
errorprone/tests/java/com/google/errorprone/bugpatterns/android/UidCheckerTest.java +69 −2 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ public class UidCheckerTest { } @Test public void testTypical() { public void testTypical_methodInvocation() { compilationHelper .addSourceLines("Example.java", "public abstract class Example {", Loading @@ -57,7 +57,30 @@ public class UidCheckerTest { } @Test public void testCallingUid() { public void testTypical_newClass() { compilationHelper .addSourceLines("Example.java", "public abstract class Example {", " class Bar { Bar(int pid, int uid, int userId) {} }", " abstract int getUserId();", " void foo(int pid, int uid, int userId, int unrelated) {", " new Bar(0, 0, 0);", " new Bar(pid, uid, userId);", " new Bar(pid, uid, getUserId());", " new Bar(unrelated, unrelated, unrelated);", " // BUG: Diagnostic contains:", " new Bar(uid, pid, userId);", " // BUG: Diagnostic contains:", " new Bar(pid, userId, uid);", " // BUG: Diagnostic contains:", " new Bar(getUserId(), 0, 0);", " }", "}") .doTest(); } @Test public void testCallingUid_methodInvocation() { compilationHelper .addSourceFile("/android/os/Binder.java") .addSourceFile("/android/os/UserHandle.java") Loading Loading @@ -98,4 +121,48 @@ public class UidCheckerTest { "}") .doTest(); } @Test public void testCallingUid_newClass() { compilationHelper .addSourceFile("/android/os/Binder.java") .addSourceFile("/android/os/UserHandle.java") .addSourceLines("Example.java", "import android.os.Binder;", "import android.os.UserHandle;", "public abstract class Example {", " int callingUserId;", " int callingUid;", " class Foo { Foo(int callingUserId) {} }", " class Bar { Bar(int callingUid) {} }", " void doUserId(int callingUserId) {", " new Foo(UserHandle.getUserId(Binder.getCallingUid()));", " new Foo(this.callingUserId);", " new Foo(callingUserId);", " // BUG: Diagnostic contains:", " new Foo(Binder.getCallingUid());", " // BUG: Diagnostic contains:", " new Foo(this.callingUid);", " // BUG: Diagnostic contains:", " new Foo(callingUid);", " }", " void doUid(int callingUserId) {", " new Bar(Binder.getCallingUid());", " new Bar(this.callingUid);", " new Bar(callingUid);", " // BUG: Diagnostic contains:", " new Bar(UserHandle.getUserId(Binder.getCallingUid()));", " // BUG: Diagnostic contains:", " new Bar(this.callingUserId);", " // BUG: Diagnostic contains:", " new Bar(callingUserId);", " }", " void doInner() {", " // BUG: Diagnostic contains:", " new Foo(UserHandle.getUserId(callingUserId));", " }", "}") .doTest(); } }