diff options
author | 2018-06-15 13:43:59 -0700 | |
---|---|---|
committer | 2018-06-15 13:45:20 -0700 | |
commit | 6caac8537902d9ee07c993d05472b01165d528e1 (patch) | |
tree | 99a79b72975f163870c3f003358182d92e46a910 /src/tools/android/java/com/google/devtools/build/android/resources | |
parent | d15440327249899c0bb9cda36996937c74e46e47 (diff) |
Fail when resources use invalid java identifiers.
RELNOTES:None
PiperOrigin-RevId: 200766836
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/resources')
3 files changed, 119 insertions, 8 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/BUILD b/src/tools/android/java/com/google/devtools/build/android/resources/BUILD index e911735cfa..a0cb57c4f4 100644 --- a/src/tools/android/java/com/google/devtools/build/android/resources/BUILD +++ b/src/tools/android/java/com/google/devtools/build/android/resources/BUILD @@ -2,7 +2,7 @@ # Tools for android resource processing package(default_visibility = [ - "//src/test/java/com/google/devtools/build/android/resources:__pkg__", + "//src/test/java/com/google/devtools/build/android:__subpackages__", "//src/tools/android/java/com/google/devtools/build/android:__pkg__", ]) diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/JavaIdentifierValidator.java b/src/tools/android/java/com/google/devtools/build/android/resources/JavaIdentifierValidator.java new file mode 100644 index 0000000000..c37798168a --- /dev/null +++ b/src/tools/android/java/com/google/devtools/build/android/resources/JavaIdentifierValidator.java @@ -0,0 +1,116 @@ +// Copyright 2018 The Bazel Authors. All rights reserved. +// +// 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.devtools.build.android.resources; + +import static java.util.stream.Collectors.joining; + +import com.google.common.collect.ImmutableSet; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +/** Validates resource identifiers and packages for java identifier validity. */ +public class JavaIdentifierValidator { + + private JavaIdentifierValidator() {} + + /** Thrown when a resource filed is not a valida java identifier. */ + public static class InvalidJavaIdentifier extends RuntimeException { + + /** Creates a new exception. */ + public InvalidJavaIdentifier(String message) { + super(message); + } + } + + /** + * Validates a resource identifier for java correctness. + * + * @param identifier an identifier derived from an android resource. + * @param additionalInformation optional information about the identifier. + * @return The identifier if valid. + * @throws InvalidJavaIdentifier if the identifier is invalid. + */ + public static String validate(String identifier, Object... additionalInformation) { + if (VALID_JAVA_IDENTIFIER.test(identifier)) { + return identifier; + } + throw new InvalidJavaIdentifier( + String.format( + "%s is an invalid java identifier %s.", + identifier, + Stream.of(additionalInformation).map(Object::toString).collect(joining(" ")))); + } + + private static final ImmutableSet<String> JAVA_RESERVED = + ImmutableSet.of( + "abstract", + "assert", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "class", + "const", + "continue", + "default", + "double", + "do", + "else", + "enum", + "extends", + "false", + "final", + "finally", + "float", + "for", + "goto", + "if", + "implements", + "import", + "instanceof", + "int", + "interface", + "long", + "native", + "new", + "null", + "package", + "private", + "protected", + "public", + "return", + "short", + "static", + "strictfp", + "super", + "switch", + "synchronized", + "this", + "throw", + "throws", + "transient", + "true", + "try", + "void", + "volatile", + "while"); + + private static final Predicate<String> VALID_JAVA_IDENTIFIER = + ((Predicate<String>) JAVA_RESERVED::contains) + .negate() + .and(Pattern.compile("^([a-zA-Z_$][a-zA-Z\\d_$]*)$").asPredicate()); +} diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java b/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java index 61bff97b79..2012a989d8 100644 --- a/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java +++ b/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java @@ -17,7 +17,6 @@ import static java.nio.file.StandardOpenOption.CREATE_NEW; import com.android.SdkConstants; import com.android.resources.ResourceType; -import com.google.common.base.Preconditions; import com.google.common.base.Splitter; import com.google.common.collect.Iterables; import java.io.IOException; @@ -142,12 +141,8 @@ public class RClassGenerator { } for (Map.Entry<String, FieldInitializer> entry : initializers.entrySet()) { FieldInitializer init = entry.getValue(); - Preconditions.checkArgument( - !entry.getKey().contains(":"), - "%s in %s, %s is invalid java id", - entry.getKey(), - packageDir, - fullyQualifiedInnerClass); + JavaIdentifierValidator.validate( + entry.getKey(), "in class:", fullyQualifiedInnerClass, "and package:", packageDir); if (init.writeFieldDefinition( entry.getKey(), innerClassWriter, fieldAccessLevel, finalFields)) { deferredInitializers.put(entry.getKey(), init); |