From aa2a1f3afe2f10baab5befcafb39df14cbffc743 Mon Sep 17 00:00:00 2001 From: Tom de Goede Date: Tue, 19 Apr 2022 09:00:31 -0700 Subject: [PATCH] Fix ZipDecompressor windows 0x80 (file attribute normal) Fixes #9236. On a rare occasion a zip file contains files with the 0x80 attribute. From https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants A file that does not have other attributes set. This attribute is valid only when used alone. Closes #15260. PiperOrigin-RevId: 442825326 --- .../lib/bazel/repository/ZipDecompressor.java | 16 ++++++++++------ .../bazel/repository/ZipDecompressorTest.java | 9 +++++++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java index 30f59f3b957f70..f2bf17cc235ddd 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java @@ -51,10 +51,11 @@ private ZipDecompressor() { private static final int S_IFREG = 0100000; private static final int S_IFLNK = 0120000; private static final int EXECUTABLE_MASK = 0755; - @VisibleForTesting - static final int WINDOWS_DIRECTORY = 0x10; - @VisibleForTesting - static final int WINDOWS_FILE = 0x20; + + // source: https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants + @VisibleForTesting static final int WINDOWS_FILE_ATTRIBUTE_DIRECTORY = 0x10; + @VisibleForTesting static final int WINDOWS_FILE_ATTRIBUTE_ARCHIVE = 0x20; + @VisibleForTesting static final int WINDOWS_FILE_ATTRIBUTE_NORMAL = 0x80; /** * This unzips the zip file to directory {@link DecompressorDescriptor#repositoryPath()}, which by @@ -186,10 +187,13 @@ static int getPermissions(int permissions, String path) throws IOException { // https://github.com/miloyip/rapidjson/archive/v1.0.2.zip, it looks like executables end up // with "normal" (posix) permissions (oddly), so they'll be handled above. int windowsPermission = permissions & 0xff; - if ((windowsPermission & WINDOWS_DIRECTORY) == WINDOWS_DIRECTORY) { + if ((windowsPermission & WINDOWS_FILE_ATTRIBUTE_DIRECTORY) + == WINDOWS_FILE_ATTRIBUTE_DIRECTORY) { // Directory. return S_IFDIR | EXECUTABLE_MASK; - } else if (permissions == 0 || (windowsPermission & WINDOWS_FILE) == WINDOWS_FILE) { + } else if (permissions == 0 + || (windowsPermission & WINDOWS_FILE_ATTRIBUTE_ARCHIVE) == WINDOWS_FILE_ATTRIBUTE_ARCHIVE + || (windowsPermission & WINDOWS_FILE_ATTRIBUTE_NORMAL) == WINDOWS_FILE_ATTRIBUTE_NORMAL) { // File. return S_IFREG | EXECUTABLE_MASK; } diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressorTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressorTest.java index 0ba47de9014a9e..88936a1218af5f 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressorTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressorTest.java @@ -85,9 +85,14 @@ public void testGetPermissions() throws Exception { @Test public void testWindowsPermissions() throws Exception { - int permissions = ZipDecompressor.getPermissions(ZipDecompressor.WINDOWS_DIRECTORY, "foo/bar"); + int permissions = + ZipDecompressor.getPermissions(ZipDecompressor.WINDOWS_FILE_ATTRIBUTE_DIRECTORY, "foo/bar"); assertThat(permissions).isEqualTo(DIRECTORY); - permissions = ZipDecompressor.getPermissions(ZipDecompressor.WINDOWS_FILE, "foo/bar"); + permissions = + ZipDecompressor.getPermissions(ZipDecompressor.WINDOWS_FILE_ATTRIBUTE_ARCHIVE, "foo/bar"); + assertThat(permissions).isEqualTo(EXECUTABLE); + permissions = + ZipDecompressor.getPermissions(ZipDecompressor.WINDOWS_FILE_ATTRIBUTE_NORMAL, "foo/bar"); assertThat(permissions).isEqualTo(EXECUTABLE); }