Skip to content

Commit 6715aa8

Browse files
committed
Force rctx.{download_and,}extract to create user-readable files
Archives in the wild do sometimes contain non-readable files, but other tools work around this and thus mask their brokenness.
1 parent 028bc1a commit 6715aa8

4 files changed

Lines changed: 12 additions & 5 deletions

File tree

src/main/java/com/google/devtools/build/lib/bazel/repository/decompressor/ArFunction.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ public Path decompress(DecompressorDescriptor descriptor)
7575
try (OutputStream out = filePath.getOutputStream()) {
7676
ByteStreams.copy(arStream, out);
7777
}
78-
filePath.chmod(entry.getMode());
78+
// Ensure that all files are at least user-readable. Some archives contain files that
79+
// are not, but many other tools are working around this and thus mask these issues.
80+
filePath.chmod(entry.getMode() | 0400);
7981
// entry.getLastModified() appears to be in seconds, so we need to convert
8082
// it into milliseconds for setLastModifiedTime
8183
filePath.setLastModifiedTime(entry.getLastModified() * 1000L);

src/main/java/com/google/devtools/build/lib/bazel/repository/decompressor/CompressedTarFunction.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ public Path decompress(DecompressorDescriptor descriptor)
164164
try (OutputStream out = filePath.getOutputStream()) {
165165
ByteStreams.copy(tarStream, out);
166166
}
167-
filePath.chmod(entry.getMode());
167+
// Ensure that all files are at least user-readable. Some archives contain files that
168+
// are not, but many other tools are working around this and thus mask these issues.
169+
filePath.chmod(entry.getMode() | 0400);
168170

169171
// This can only be done on real files, not links, or it will skip the reader to
170172
// the next "real" file to try to find the mod time info.

src/main/java/com/google/devtools/build/lib/bazel/repository/decompressor/ZipDecompressor.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,9 @@ private static void extractZipEntry(
172172
throw new InterruptedException();
173173
}
174174
}
175-
outputPath.chmod(permissions);
175+
// Ensure that all files are at least user-readable. Some archives contain files that
176+
// are not, but many other tools are working around this and thus mask these issues.
177+
outputPath.chmod(permissions | 0400);
176178
outputPath.setLastModifiedTime(entry.getTime());
177179
}
178180
}

src/test/shell/bazel/starlark_repository_test.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3646,10 +3646,11 @@ function test_extract_non_readable_file_zip() {
36463646
echo "secret zip content" > non_readable_zip_dir/non_readable.txt
36473647
python3 -c "
36483648
import zipfile
3649-
import os
36503649
with zipfile.ZipFile('non_readable.zip', 'w') as zf:
36513650
info = zipfile.ZipInfo('non_readable_zip_dir/non_readable.txt')
3652-
info.external_attr = 0o000 << 16 # No permissions
3651+
# S_IFREG (0o100000) marks it as a regular file, but with no permission bits.
3652+
# This ensures getPermissions() returns the actual mode rather than defaulting to 0755.
3653+
info.external_attr = 0o100000 << 16
36533654
zf.writestr(info, 'secret zip content')
36543655
"
36553656
popd

0 commit comments

Comments
 (0)