Version 1.2.28.
Merge: Do not use Paths.get on ZipEntry names.
CL: https://r8-review.googlesource.com/c/r8/+/22466
Merge: Fix FilteredClassPathTest on Windows to not assume the use of Path objects.
CL: https://r8-review.googlesource.com/c/r8/+/22466
R=sgjesse@google.com
Bug: 109992855
Change-Id: Ie7f08bcfc21085856c564d57d2ca256c74b6ffac
diff --git a/src/main/java/com/android/tools/r8/ArchiveClassFileProvider.java b/src/main/java/com/android/tools/r8/ArchiveClassFileProvider.java
index af83158..a6389da 100644
--- a/src/main/java/com/android/tools/r8/ArchiveClassFileProvider.java
+++ b/src/main/java/com/android/tools/r8/ArchiveClassFileProvider.java
@@ -12,7 +12,7 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.DescriptorUtils;
-import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.ZipUtils;
import com.google.common.io.ByteStreams;
import java.io.Closeable;
import java.io.IOException;
@@ -21,7 +21,6 @@
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
@@ -73,7 +72,7 @@
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String name = entry.getName();
- if (FileUtils.isClassFile(Paths.get(name)) && include.test(name)) {
+ if (ZipUtils.isClassFile(name) && include.test(name)) {
descriptors.add(DescriptorUtils.guessTypeDescriptor(name));
}
}
diff --git a/src/main/java/com/android/tools/r8/ArchiveProgramResourceProvider.java b/src/main/java/com/android/tools/r8/ArchiveProgramResourceProvider.java
index 425b3c3..1d6e678 100644
--- a/src/main/java/com/android/tools/r8/ArchiveProgramResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/ArchiveProgramResourceProvider.java
@@ -3,22 +3,18 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
-import static com.android.tools.r8.utils.FileUtils.isClassFile;
-import static com.android.tools.r8.utils.FileUtils.isDexFile;
-
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.origin.ArchiveEntryOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.DescriptorUtils;
-import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.ZipUtils;
import com.google.common.io.ByteStreams;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -39,16 +35,15 @@
}
public static boolean includeClassFileEntries(String entry) {
- return isClassFile(Paths.get(entry));
+ return ZipUtils.isClassFile(entry);
}
public static boolean includeDexEntries(String entry) {
- return isDexFile(Paths.get(entry));
+ return ZipUtils.isDexFile(entry);
}
public static boolean includeClassFileOrDexEntries(String entry) {
- Path path = Paths.get(entry);
- return isClassFile(path) || isDexFile(path);
+ return ZipUtils.isClassFile(entry) || ZipUtils.isDexFile(entry);
}
private final Origin origin;
@@ -97,14 +92,13 @@
ZipEntry entry = entries.nextElement();
try (InputStream stream = zipFile.getInputStream(entry)) {
String name = entry.getName();
- Path path = Paths.get(name);
- Origin entryOrigin = new ArchiveEntryOrigin(entry.getName(), origin);
+ Origin entryOrigin = new ArchiveEntryOrigin(name, origin);
if (include.test(name)) {
- if (FileUtils.isDexFile(path)) {
+ if (ZipUtils.isDexFile(name)) {
dexResources.add(
ProgramResource.fromBytes(
entryOrigin, Kind.DEX, ByteStreams.toByteArray(stream), null));
- } else if (isClassFile(path)) {
+ } else if (ZipUtils.isClassFile(name)) {
String descriptor = DescriptorUtils.guessTypeDescriptor(name);
classResources.add(
ProgramResource.fromBytes(
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 02c5f8e..9271ea6 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "1.2.27";
+ public static final String LABEL = "1.2.28";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/benchmarks/FrameworkIncrementalDexingBenchmark.java b/src/main/java/com/android/tools/r8/benchmarks/FrameworkIncrementalDexingBenchmark.java
index 1336f95..807509a 100644
--- a/src/main/java/com/android/tools/r8/benchmarks/FrameworkIncrementalDexingBenchmark.java
+++ b/src/main/java/com/android/tools/r8/benchmarks/FrameworkIncrementalDexingBenchmark.java
@@ -22,7 +22,6 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.DescriptorUtils;
-import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.ZipUtils;
import com.google.common.collect.ImmutableMap;
@@ -61,7 +60,7 @@
archive.toString(),
(entry, stream) -> {
String name = entry.getName();
- if (FileUtils.isClassFile(Paths.get(name))) {
+ if (ZipUtils.isClassFile(name)) {
String descriptor = DescriptorUtils.guessTypeDescriptor(name);
builder.put(descriptor, ByteStreams.toByteArray(stream));
}
diff --git a/src/main/java/com/android/tools/r8/compatdx/CompatDx.java b/src/main/java/com/android/tools/r8/compatdx/CompatDx.java
index 871f6d8..7d2907a 100644
--- a/src/main/java/com/android/tools/r8/compatdx/CompatDx.java
+++ b/src/main/java/com/android/tools/r8/compatdx/CompatDx.java
@@ -3,13 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.compatdx;
-import static com.android.tools.r8.utils.FileUtils.isApkFile;
-import static com.android.tools.r8.utils.FileUtils.isArchive;
-import static com.android.tools.r8.utils.FileUtils.isClassFile;
-import static com.android.tools.r8.utils.FileUtils.isDexFile;
-import static com.android.tools.r8.utils.FileUtils.isJarFile;
-import static com.android.tools.r8.utils.FileUtils.isZipFile;
-
import com.android.tools.r8.CompatDxHelper;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
@@ -28,6 +21,7 @@
import com.android.tools.r8.utils.ExceptionDiagnostic;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.ThreadUtils;
+import com.android.tools.r8.utils.ZipUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import java.io.File;
@@ -475,7 +469,7 @@
}
if (singleDexFile) {
return new SingleDexFileConsumer(
- isDexFile(output)
+ FileUtils.isDexFile(output)
? new NamedDexFileConsumer(output)
: createDexConsumer(output, inputs, keepClasses));
}
@@ -486,13 +480,13 @@
Path output, List<Path> inputs, boolean keepClasses)
throws DxUsageMessage {
if (keepClasses) {
- if (!isArchive(output)) {
+ if (!FileUtils.isArchive(output)) {
throw new DxCompatOptions.DxUsageMessage(
"Output must be an archive when --keep-classes is set.");
}
return new DexKeepClassesConsumer(output, inputs);
}
- return isArchive(output)
+ return FileUtils.isArchive(output)
? new DexIndexedConsumer.ArchiveConsumer(output)
: new DexIndexedConsumer.DirectoryConsumer(output);
}
@@ -572,12 +566,12 @@
private void writeZipWithClasses(DiagnosticsHandler handler) throws IOException {
// For each input archive file, add all class files within.
for (Path input : inputs) {
- if (isArchive(input)) {
+ if (FileUtils.isArchive(input)) {
try (ZipFile zipFile = new ZipFile(input.toFile(), StandardCharsets.UTF_8)) {
final Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
- if (isClassFile(Paths.get(entry.getName()))) {
+ if (ZipUtils.isClassFile(entry.getName())) {
try (InputStream entryStream = zipFile.getInputStream(entry)) {
outputBuilder.addFile(
entry.getName(), ByteStreams.toByteArray(entryStream), handler);
@@ -604,11 +598,11 @@
return;
}
Path path = file.toPath();
- if (isZipFile(path) || isJarFile(path) || isClassFile(path)) {
+ if (FileUtils.isZipFile(path) || FileUtils.isJarFile(path) || FileUtils.isClassFile(path)) {
files.add(path);
return;
}
- if (isApkFile(path)) {
+ if (FileUtils.isApkFile(path)) {
throw new Unimplemented("apk files not yet supported");
}
}
diff --git a/src/main/java/com/android/tools/r8/shaking/FilteredClassPath.java b/src/main/java/com/android/tools/r8/shaking/FilteredClassPath.java
index 1eb11e9..c67af00 100644
--- a/src/main/java/com/android/tools/r8/shaking/FilteredClassPath.java
+++ b/src/main/java/com/android/tools/r8/shaking/FilteredClassPath.java
@@ -46,14 +46,14 @@
return path;
}
- public boolean matchesFile(Path file) {
+ public boolean matchesFile(String name) {
if (isUnfiltered()) {
return true;
}
boolean isNegated = false;
for (String pattern : pattern) {
isNegated = pattern.charAt(0) == '!';
- boolean matches = matchAgainstFileName(file.toString(), 0, pattern, isNegated ? 1 : 0);
+ boolean matches = matchAgainstFileName(name, 0, pattern, isNegated ? 1 : 0);
if (matches) {
return !isNegated;
}
@@ -63,7 +63,7 @@
}
private boolean containsFileSeparator(String string) {
- return string.indexOf(File.separatorChar) != -1;
+ return string.indexOf('/') != -1;
}
private boolean matchAgainstFileName(String fileName, int namePos, String pattern,
@@ -95,7 +95,7 @@
}
} else {
for (int i = namePos; i < fileName.length(); i++) {
- if (!includeFileSeparators && fileName.charAt(i) == File.separatorChar) {
+ if (!includeFileSeparators && fileName.charAt(i) == '/') {
return false;
}
if (matchAgainstFileName(fileName, i, pattern, patternPos + 1)) {
diff --git a/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java b/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java
index 0f06ca8..a611105 100644
--- a/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java
+++ b/src/main/java/com/android/tools/r8/utils/ArchiveResourceProvider.java
@@ -4,8 +4,6 @@
package com.android.tools.r8.utils;
import static com.android.tools.r8.utils.FileUtils.isArchive;
-import static com.android.tools.r8.utils.FileUtils.isClassFile;
-import static com.android.tools.r8.utils.FileUtils.isDexFile;
import com.android.tools.r8.DataDirectoryResource;
import com.android.tools.r8.DataEntryResource;
@@ -23,8 +21,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -56,17 +52,16 @@
ZipEntry entry = entries.nextElement();
try (InputStream stream = zipFile.getInputStream(entry)) {
String name = entry.getName();
- Path path = Paths.get(name);
Origin entryOrigin = new ArchiveEntryOrigin(name, origin);
- if (archive.matchesFile(path)) {
- if (isDexFile(path)) {
+ if (archive.matchesFile(name)) {
+ if (ZipUtils.isDexFile(name)) {
if (!ignoreDexInArchive) {
ProgramResource resource =
OneShotByteResource.create(
Kind.DEX, entryOrigin, ByteStreams.toByteArray(stream), null);
dexResources.add(resource);
}
- } else if (isClassFile(path)) {
+ } else if (ZipUtils.isClassFile(name)) {
String descriptor = DescriptorUtils.guessTypeDescriptor(name);
ProgramResource resource =
OneShotByteResource.create(
@@ -111,7 +106,7 @@
final Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
- Path name = Paths.get(entry.getName());
+ String name = entry.getName();
if (archive.matchesFile(name) && !isProgramResourceName(name)) {
if (entry.isDirectory()) {
resourceBrowser.visit(DataDirectoryResource.fromZip(zipFile, entry));
@@ -129,7 +124,7 @@
}
}
- private boolean isProgramResourceName(Path name) {
- return isClassFile(name) || (isDexFile(name) && !ignoreDexInArchive);
+ private boolean isProgramResourceName(String name) {
+ return ZipUtils.isClassFile(name) || (ZipUtils.isDexFile(name) && !ignoreDexInArchive);
}
}
diff --git a/src/main/java/com/android/tools/r8/utils/FilteredArchiveClassFileProvider.java b/src/main/java/com/android/tools/r8/utils/FilteredArchiveClassFileProvider.java
index f933b42..0c6cc14 100644
--- a/src/main/java/com/android/tools/r8/utils/FilteredArchiveClassFileProvider.java
+++ b/src/main/java/com/android/tools/r8/utils/FilteredArchiveClassFileProvider.java
@@ -6,12 +6,11 @@
import com.android.tools.r8.ArchiveClassFileProvider;
import com.android.tools.r8.shaking.FilteredClassPath;
import java.io.IOException;
-import java.nio.file.Paths;
// Internal filtered class-file provider.
class FilteredArchiveClassFileProvider extends ArchiveClassFileProvider {
FilteredArchiveClassFileProvider(FilteredClassPath archive) throws IOException {
- super(archive.getPath(), entry -> archive.matchesFile(Paths.get(entry)));
+ super(archive.getPath(), entry -> archive.matchesFile(entry));
}
}
diff --git a/src/main/java/com/android/tools/r8/utils/ZipUtils.java b/src/main/java/com/android/tools/r8/utils/ZipUtils.java
index 849377b..fd50583 100644
--- a/src/main/java/com/android/tools/r8/utils/ZipUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ZipUtils.java
@@ -3,6 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.utils;
+import static com.android.tools.r8.utils.FileUtils.CLASS_EXTENSION;
+import static com.android.tools.r8.utils.FileUtils.DEX_EXTENSION;
+import static com.android.tools.r8.utils.FileUtils.MODULE_INFO_CLASS;
+
import com.android.tools.r8.errors.CompilationError;
import com.google.common.io.ByteStreams;
import java.io.File;
@@ -92,4 +96,17 @@
stream.write(content);
stream.closeEntry();
}
+
+ public static boolean isDexFile(String entry) {
+ String name = entry.toLowerCase();
+ return name.endsWith(DEX_EXTENSION);
+ }
+
+ public static boolean isClassFile(String entry) {
+ String name = entry.toLowerCase();
+ if (name.endsWith(MODULE_INFO_CLASS)) {
+ return false;
+ }
+ return name.endsWith(CLASS_EXTENSION);
+ }
}
diff --git a/src/test/apiUsageSample/com/android/tools/apiusagesample/D8ApiUsageSample.java b/src/test/apiUsageSample/com/android/tools/apiusagesample/D8ApiUsageSample.java
index 2ef0123..23dc7e0 100644
--- a/src/test/apiUsageSample/com/android/tools/apiusagesample/D8ApiUsageSample.java
+++ b/src/test/apiUsageSample/com/android/tools/apiusagesample/D8ApiUsageSample.java
@@ -391,8 +391,9 @@
ZipInputStream zip = new ZipInputStream(Files.newInputStream(file), StandardCharsets.UTF_8);
ZipEntry entry;
while (null != (entry = zip.getNextEntry())) {
- if (isClassFile(Paths.get(entry.getName()))) {
- Origin origin = new ArchiveEntryOrigin(entry.getName(), zipOrigin);
+ String name = entry.getName();
+ if (isClassFile(name)) {
+ Origin origin = new ArchiveEntryOrigin(name, zipOrigin);
classfiles.add(new ClassFileContent(origin, readBytes(zip)));
}
}
diff --git a/src/test/apiUsageSample/com/android/tools/apiusagesample/R8ApiUsageSample.java b/src/test/apiUsageSample/com/android/tools/apiusagesample/R8ApiUsageSample.java
index 2c2e8d7..7bce10a 100644
--- a/src/test/apiUsageSample/com/android/tools/apiusagesample/R8ApiUsageSample.java
+++ b/src/test/apiUsageSample/com/android/tools/apiusagesample/R8ApiUsageSample.java
@@ -382,8 +382,9 @@
ZipInputStream zip = new ZipInputStream(Files.newInputStream(file), StandardCharsets.UTF_8);
ZipEntry entry;
while (null != (entry = zip.getNextEntry())) {
- if (isClassFile(Paths.get(entry.getName()))) {
- Origin origin = new ArchiveEntryOrigin(entry.getName(), zipOrigin);
+ String name = entry.getName();
+ if (isClassFile(name)) {
+ Origin origin = new ArchiveEntryOrigin(name, zipOrigin);
classfiles.add(new ClassFileContent(origin, readBytes(zip)));
}
}
diff --git a/src/test/java/com/android/tools/r8/ArchiveClassFileProviderTest.java b/src/test/java/com/android/tools/r8/ArchiveClassFileProviderTest.java
new file mode 100644
index 0000000..6ceb0a2
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ArchiveClassFileProviderTest.java
@@ -0,0 +1,43 @@
+// Copyright (c) 2018 the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class ArchiveClassFileProviderTest {
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ public Path createZip() throws IOException {
+ Path tempRoot = temporaryFolder.getRoot().toPath();
+ Path zipFile = tempRoot.resolve("zipfile.zip");
+ ZipOutputStream zipStream =
+ new ZipOutputStream(new FileOutputStream(zipFile.toFile()), StandardCharsets.UTF_8);
+ ZipEntry entry = new ZipEntry("non-ascii:$\u02CF");
+ zipStream.putNextEntry(entry);
+ zipStream.write(10);
+ zipStream.close();
+ return zipFile;
+ }
+
+ @Test
+ public void testSystemLocale() throws IOException, ResourceException {
+ // Set the locale used for Paths to ASCII which will make Path creation fail
+ // for non-ascii names.
+ System.setProperty("sun.jnu.encoding", "ASCII");
+ Path zipFile = createZip();
+ new ArchiveClassFileProvider(zipFile);
+ ArchiveProgramResourceProvider.fromArchive(zipFile).getProgramResources();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/shaking/FilteredClassPathTest.java b/src/test/java/com/android/tools/r8/shaking/FilteredClassPathTest.java
index f27813e..7c243ae 100644
--- a/src/test/java/com/android/tools/r8/shaking/FilteredClassPathTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/FilteredClassPathTest.java
@@ -34,16 +34,8 @@
private void testPath(List<String> filters, List<String> positives, List<String> negatives) {
FilteredClassPath path = makeFilteredClassPath(filters);
- Assert.assertTrue(
- positives.stream().map(FilteredClassPathTest::adaptFileSeparator).map(Paths::get)
- .allMatch(path::matchesFile));
- Assert.assertFalse(
- negatives.stream().map(FilteredClassPathTest::adaptFileSeparator).map(Paths::get)
- .allMatch(path::matchesFile));
- }
-
- private static String adaptFileSeparator(String s) {
- return s.replace('/', File.separatorChar);
+ Assert.assertTrue(positives.stream().allMatch(path::matchesFile));
+ Assert.assertFalse(negatives.stream().allMatch(path::matchesFile));
}
private static FilteredClassPath makeFilteredClassPath(List<String> filters) {
@@ -51,9 +43,7 @@
}
private static FilteredClassPath makeFilteredClassPath(Path path, List<String> filters) {
- return new FilteredClassPath(path,
- filters.stream().map(FilteredClassPathTest::adaptFileSeparator)
- .collect(ImmutableList.toImmutableList()));
+ return new FilteredClassPath(path, ImmutableList.copyOf(filters));
}
@Test