Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 945e3341 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Expand UidChecker to check new class initializations.

Bug: 162543841
Test: atest ./errorprone/tests/java/com/google/errorprone/bugpatterns/android/UidCheckerTest.java
Change-Id: Id013a6416f687411567fa3d363c917106ab3608e
parent 6a839164
Loading
Loading
Loading
Loading
+15 −3
Original line number Original line Diff line number Diff line
@@ -23,12 +23,15 @@ import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
import com.google.errorprone.bugpatterns.BugChecker.NewClassTreeMatcher;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
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 com.sun.tools.javac.code.Symbol.VarSymbol;


import java.util.List;
import java.util.List;
@@ -44,11 +47,20 @@ import java.util.regex.Pattern;
    name = "AndroidFrameworkUid",
    name = "AndroidFrameworkUid",
    summary = "Verifies that PID, UID and user ID arguments aren't crossed",
    summary = "Verifies that PID, UID and user ID arguments aren't crossed",
    severity = WARNING)
    severity = WARNING)
public final class UidChecker extends BugChecker implements MethodInvocationTreeMatcher {
public final class UidChecker extends BugChecker implements MethodInvocationTreeMatcher,
        NewClassTreeMatcher {
    @Override
    @Override
    public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
        final List<VarSymbol> vars = ASTHelpers.getSymbol(tree).params();
        return matchArguments(ASTHelpers.getSymbol(tree).params(), tree.getArguments(), tree);
        final List<? extends ExpressionTree> args = tree.getArguments();
    }

    @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++) {
        for (int i = 0; i < Math.min(vars.size(), args.size()); i++) {
            final Flavor varFlavor = getFlavor(vars.get(i));
            final Flavor varFlavor = getFlavor(vars.get(i));
            final Flavor argFlavor = getFlavor(args.get(i));
            final Flavor argFlavor = getFlavor(args.get(i));
+69 −2
Original line number Original line Diff line number Diff line
@@ -34,7 +34,7 @@ public class UidCheckerTest {
    }
    }


    @Test
    @Test
    public void testTypical() {
    public void testTypical_methodInvocation() {
        compilationHelper
        compilationHelper
                .addSourceLines("Example.java",
                .addSourceLines("Example.java",
                        "public abstract class Example {",
                        "public abstract class Example {",
@@ -57,7 +57,30 @@ public class UidCheckerTest {
    }
    }


    @Test
    @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
        compilationHelper
                .addSourceFile("/android/os/Binder.java")
                .addSourceFile("/android/os/Binder.java")
                .addSourceFile("/android/os/UserHandle.java")
                .addSourceFile("/android/os/UserHandle.java")
@@ -98,4 +121,48 @@ public class UidCheckerTest {
                        "}")
                        "}")
                .doTest();
                .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();
    }
}
}