Skip to content

Commit b9eedea

Browse files
committed
Panic if dist generates a symbolic link in a generated tarball
This avoids regressions in rustup-toolchain-install-master
1 parent 532be94 commit b9eedea

File tree

4 files changed

+27
-2
lines changed

4 files changed

+27
-2
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ dependencies = [
225225
"serde_json",
226226
"tar",
227227
"toml",
228+
"walkdir",
228229
"winapi",
229230
"xz2",
230231
]

src/bootstrap/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ ignore = "0.4.10"
4848
opener = "0.5"
4949
once_cell = "1.7.2"
5050
xz2 = "0.1"
51+
walkdir = "2"
5152

5253
[target.'cfg(windows)'.dependencies.winapi]
5354
version = "0.3"

src/bootstrap/dist.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,12 @@ impl Step for PlainSourceTarball {
848848

849849
/// Creates the plain source tarball
850850
fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
851-
let tarball = Tarball::new(builder, "rustc", "src");
851+
// NOTE: This is a strange component in a lot of ways. It uses `src` as the target, which
852+
// means neither rustup nor rustup-toolchain-install-master know how to download it.
853+
// It also contains symbolic links, unlike other any other dist tarball.
854+
// It's used for distros building rustc from source in a pre-vendored environment.
855+
let mut tarball = Tarball::new(builder, "rustc", "src");
856+
tarball.permit_symlinks(true);
852857
let plain_dst_src = tarball.image_dir();
853858

854859
// This is the set of root paths which will become part of the source package

src/bootstrap/tarball.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ pub(crate) struct Tarball<'a> {
102102

103103
include_target_in_component_name: bool,
104104
is_preview: bool,
105+
permit_symlinks: bool,
105106
}
106107

107108
impl<'a> Tarball<'a> {
@@ -141,6 +142,7 @@ impl<'a> Tarball<'a> {
141142

142143
include_target_in_component_name: false,
143144
is_preview: false,
145+
permit_symlinks: false,
144146
}
145147
}
146148

@@ -160,6 +162,10 @@ impl<'a> Tarball<'a> {
160162
self.is_preview = is;
161163
}
162164

165+
pub(crate) fn permit_symlinks(&mut self, flag: bool) {
166+
self.permit_symlinks = flag;
167+
}
168+
163169
pub(crate) fn image_dir(&self) -> &Path {
164170
t!(std::fs::create_dir_all(&self.image_dir));
165171
&self.image_dir
@@ -316,6 +322,18 @@ impl<'a> Tarball<'a> {
316322
}
317323
self.builder.run(&mut cmd);
318324

325+
// Ensure there are no symbolic links in the tarball. In particular,
326+
// rustup-toolchain-install-master and most versions of Windows can't handle symbolic links.
327+
let decompressed_output = self.temp_dir.join(&package_name);
328+
if !self.builder.config.dry_run && !self.permit_symlinks {
329+
for entry in walkdir::WalkDir::new(&decompressed_output) {
330+
let entry = t!(entry);
331+
if entry.path_is_symlink() {
332+
panic!("generated a symlink in a tarball: {}", entry.path().display());
333+
}
334+
}
335+
}
336+
319337
// Use either the first compression format defined, or "gz" as the default.
320338
let ext = self
321339
.builder
@@ -328,7 +346,7 @@ impl<'a> Tarball<'a> {
328346

329347
GeneratedTarball {
330348
path: crate::dist::distdir(self.builder).join(format!("{}.tar.{}", package_name, ext)),
331-
decompressed_output: self.temp_dir.join(package_name),
349+
decompressed_output,
332350
work: self.temp_dir,
333351
}
334352
}

0 commit comments

Comments
 (0)