diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java index 2fdd7e4f6b1692..1b1b69d589b317 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java @@ -42,12 +42,14 @@ import com.google.devtools.build.lib.analysis.test.TestProvider.TestParams; import com.google.devtools.build.lib.analysis.test.TestTagsProvider; import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.cmdline.RepositoryMapping; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.packages.AllowlistChecker; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.BuildSetting; +import com.google.devtools.build.lib.packages.BuiltinRestriction; import com.google.devtools.build.lib.packages.Info; import com.google.devtools.build.lib.packages.Provider; import com.google.devtools.build.lib.packages.TargetUtils; @@ -349,7 +351,11 @@ private void propagateTransitiveValidationOutputGroups() { Label rdeLabel = ruleContext.getRule().getRuleClassObject().getRuleDefinitionEnvironmentLabel(); // only allow native and builtins to override transitive validation propagation - if (rdeLabel != null && !rdeLabel.getRepository().getName().equals("_builtins")) { + if (rdeLabel != null + && BuiltinRestriction.isNotAllowed( + rdeLabel, + RepositoryMapping.ALWAYS_FALLBACK, + BuiltinRestriction.INTERNAL_STARLARK_API_ALLOWLIST)) { ruleContext.ruleError(rdeLabel + " cannot access the _transitive_validation private API"); return; } diff --git a/src/main/java/com/google/devtools/build/lib/packages/BuiltinRestriction.java b/src/main/java/com/google/devtools/build/lib/packages/BuiltinRestriction.java index 921bd6283f5f54..9c17e76d5f1295 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/BuiltinRestriction.java +++ b/src/main/java/com/google/devtools/build/lib/packages/BuiltinRestriction.java @@ -49,6 +49,10 @@ public final class BuiltinRestriction { BuiltinRestriction.allowlistEntry("rules_android", ""), BuiltinRestriction.allowlistEntry("build_bazel_rules_android", ""), + // Java rules + BuiltinRestriction.allowlistEntry("", "third_party/bazel_rules/rules_java"), + BuiltinRestriction.allowlistEntry("rules_java", ""), + // Rust rules BuiltinRestriction.allowlistEntry( "", "third_party/bazel_rules/rules_rust/rust/private"), @@ -147,12 +151,20 @@ public static void failIfModuleOutsideAllowlist( public static void failIfLabelOutsideAllowlist( Label label, RepositoryMapping repoMapping, Collection allowlist) throws EvalException { - if (label.getRepository().getName().equals("_builtins")) { - return; - } - if (allowlist.stream().noneMatch(e -> e.allows(label, repoMapping))) { + if (isNotAllowed(label, repoMapping, allowlist)) { throw Starlark.errorf("file '%s' cannot use private API", label.getCanonicalForm()); } } - + + /** + * Returns true if the given {@link Label} is not within both 1) the builtins repository, or 2) a + * package or subpackage of an entry in the given allowlist. + */ + public static boolean isNotAllowed( + Label label, RepositoryMapping repoMapping, Collection allowlist) { + if (label.getRepository().getName().equals("_builtins")) { + return false; + } + return allowlist.stream().noneMatch(e -> e.allows(label, repoMapping)); + } } diff --git a/src/test/java/com/google/devtools/build/lib/analysis/TransitiveValidationPropagationTest.java b/src/test/java/com/google/devtools/build/lib/analysis/TransitiveValidationPropagationTest.java index cdb83e43395015..8d6ee4f1b2c5c8 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/TransitiveValidationPropagationTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/TransitiveValidationPropagationTest.java @@ -162,7 +162,7 @@ public void testValidationOutputPropagation() throws Exception { @Test public void testTransitiveValidationOutputGroupNotAllowedForStarlarkRules() throws Exception { scratch.file( - "test/foo_rule.bzl", + "foobar/foo_rule.bzl", """ def _impl(ctx): return [OutputGroupInfo(_validation_transitive = depset())] @@ -170,18 +170,18 @@ def _impl(ctx): foo_rule = rule(implementation = _impl) """); scratch.file( - "test/BUILD", + "foobar/BUILD", """ - load("//test:foo_rule.bzl", "foo_rule") + load("//foobar:foo_rule.bzl", "foo_rule") foo_rule(name = "foo") """); AssertionError expected = - assertThrows(AssertionError.class, () -> getConfiguredTarget("//test:foo")); + assertThrows(AssertionError.class, () -> getConfiguredTarget("//foobar:foo")); assertThat(expected) .hasMessageThat() - .contains("//test:foo_rule.bzl cannot access the _transitive_validation private API"); + .contains("//foobar:foo_rule.bzl cannot access the _transitive_validation private API"); } }