diff options
author | 2023-05-22 17:21:19 +1000 | |
---|---|---|
committer | 2023-05-23 12:19:43 +1000 | |
commit | e63cb8fab608b60a9385efbabfff6e2722240a09 (patch) | |
tree | 0fd49e465d19424b8db04b2ae80cf961762b38d4 | |
parent | 31e1f9f8fa53bee19063f8c468005495b757e20d (diff) |
Support @EnforcePermission annotation
Update RequiresPermissionChecker to support a method annotated with
@EnforcePermission. If encountered, we assume that the implementation is
enforcing the declared permissions (this is verified by another linter).
Bug: 239369037
Test: atest --host error_prone_android_framework_test
Change-Id: I25deb47acc1259a1171954aeebd72eb60f01fc49
4 files changed, 115 insertions, 4 deletions
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java index d39d4b466143..7c7cb18afc4d 100644 --- a/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java +++ b/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java @@ -27,6 +27,7 @@ import static com.google.errorprone.matchers.Matchers.methodInvocation; import static com.google.errorprone.matchers.Matchers.methodIsNamed; import static com.google.errorprone.matchers.Matchers.staticMethod; +import android.annotation.EnforcePermission; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; @@ -290,6 +291,13 @@ public final class RequiresPermissionChecker extends BugChecker if (perm.anyOf() != null) this.anyOf.addAll(Arrays.asList(perm.anyOf())); } + public void addAll(EnforcePermission perm) { + if (perm == null) return; + if (!perm.value().isEmpty()) this.allOf.add(perm.value()); + if (perm.allOf() != null) this.allOf.addAll(Arrays.asList(perm.allOf())); + if (perm.anyOf() != null) this.anyOf.addAll(Arrays.asList(perm.anyOf())); + } + public void addConstValue(Tree tree) { final Object value = ASTHelpers.constValue(tree); if (value != null) { @@ -416,14 +424,20 @@ public final class RequiresPermissionChecker extends BugChecker final ParsedRequiresPermission res = new ParsedRequiresPermission(); res.allOf.add(String.valueOf(ASTHelpers.constValue(tree.getArguments().get(0)))); return res; - } else if (ENFORCE_VIA_CHECKER.matches(tree, state) && tree.getArguments().size() > 1) { + } + if (ENFORCE_VIA_CHECKER.matches(tree, state) && tree.getArguments().size() > 1) { final ParsedRequiresPermission res = new ParsedRequiresPermission(); res.allOf.add(String.valueOf(ASTHelpers.constValue(tree.getArguments().get(1)))); return res; - } else { - final MethodSymbol method = ASTHelpers.getSymbol(tree); - return parseRequiresPermissionRecursively(method, state); } + final MethodSymbol method = ASTHelpers.getSymbol(tree); + final EnforcePermission enforced = method.getAnnotation(EnforcePermission.class); + if (enforced != null) { + final ParsedRequiresPermission res = new ParsedRequiresPermission(); + res.addAll(enforced); + return res; + } + return parseRequiresPermissionRecursively(method, state); } /** diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java index 38831b193610..e53372d97f3d 100644 --- a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java +++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java @@ -438,4 +438,43 @@ public class RequiresPermissionCheckerTest { "}") .doTest(); } + + @Test + public void testEnforce() { + compilationHelper + .addSourceFile("/android/annotation/EnforcePermission.java") + .addSourceFile("/android/content/Context.java") + .addSourceFile("/android/foo/IBarService.java") + .addSourceFile("/android/os/IInterface.java") + .addSourceLines("BarService.java", + "import android.annotation.EnforcePermission;", + "import android.foo.IBarService;", + "class BarService extends IBarService.Stub {", + " @Override", + " @EnforcePermission(\"INTERNET\")", + " public void bar() {", + " bar_enforcePermission();", + " }", + "}") + .addSourceLines("BarManager.java", + "import android.annotation.RequiresPermission;", + "class BarManager {", + " BarService mService;", + " @RequiresPermission(\"INTERNET\")", + " public void callBar() {", + " mService.bar();", + " }", + " @RequiresPermission(\"NONE\")", + " public void callBarDifferent() {", + " // BUG: Diagnostic contains:", + " mService.bar();", + " }", + " public void callBarMissing() {", + " // BUG: Diagnostic contains:", + " mService.bar();", + " }", + "}") + .doTest(); + } + } diff --git a/errorprone/tests/res/android/annotation/EnforcePermission.java b/errorprone/tests/res/android/annotation/EnforcePermission.java new file mode 100644 index 000000000000..26644a29928e --- /dev/null +++ b/errorprone/tests/res/android/annotation/EnforcePermission.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * 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 android.annotation; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(CLASS) +@Target({METHOD}) +public @interface EnforcePermission { + String value() default ""; + String[] allOf() default {}; + String[] anyOf() default {}; +} diff --git a/errorprone/tests/res/android/foo/IBarService.java b/errorprone/tests/res/android/foo/IBarService.java new file mode 100644 index 000000000000..058d02611316 --- /dev/null +++ b/errorprone/tests/res/android/foo/IBarService.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * 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 android.foo; + +import android.annotation.EnforcePermission; + +public interface IBarService extends android.os.IInterface { + @EnforcePermission("INTERNET") + void bar(); + + abstract class Stub implements IBarService { + public void bar_enforcePermission() { } + } +} |