Skip to content

Commit 188b8d0

Browse files
authored
Merge pull request #2555 from kinnison/fix-2376
Validate target triple in build script
2 parents 51222df + ef4e933 commit 188b8d0

File tree

5 files changed

+191
-155
lines changed

5 files changed

+191
-155
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ version = "0.3"
100100
[dev-dependencies]
101101
walkdir = "2"
102102

103+
[build-dependencies]
104+
lazy_static = "1"
105+
regex = "1"
106+
103107
[workspace]
104108
members = ["download"]
105109

build.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
11
use std::env;
22

3+
include!("src/dist/triple.rs");
4+
5+
pub fn from_build() -> Result<PartialTargetTriple, String> {
6+
let triple = if let Ok(triple) = env::var("RUSTUP_OVERRIDE_BUILD_TRIPLE") {
7+
triple
8+
} else {
9+
env::var("TARGET").unwrap()
10+
};
11+
PartialTargetTriple::new(&triple).ok_or(triple)
12+
}
13+
314
fn main() {
15+
println!("cargo:rerun-if-env-changed=RUSTUP_OVERRIDE_BUILD_TRIPLE");
16+
println!("cargo:rerun-if-env-changed=TARGET");
17+
match from_build() {
18+
Ok(triple) => eprintln!("Computed build based partial target triple: {:#?}", triple),
19+
Err(s) => {
20+
eprintln!("Unable to parse target '{}' as a PartialTargetTriple", s);
21+
eprintln!(
22+
"If you are attempting to bootstrap a new target you may need to adjust the\n\
23+
permitted values found in src/dist/triple.rs"
24+
);
25+
std::process::abort();
26+
}
27+
}
428
let target = env::var("TARGET").unwrap();
529
println!("cargo:rustc-env=TARGET={}", target);
630
}

src/dist/dist.rs

Lines changed: 1 addition & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::dist::manifestation::{Changes, Manifestation, UpdateStatus};
1414
use crate::dist::notifications::*;
1515
use crate::dist::prefix::InstallPrefix;
1616
use crate::dist::temp;
17+
pub use crate::dist::triple::*;
1718
use crate::errors::*;
1819
use crate::process;
1920
use crate::utils::utils;
@@ -52,13 +53,6 @@ pub struct PartialToolchainDesc {
5253
pub target: PartialTargetTriple,
5354
}
5455

55-
#[derive(Debug, Clone, PartialEq)]
56-
pub struct PartialTargetTriple {
57-
pub arch: Option<String>,
58-
pub os: Option<String>,
59-
pub env: Option<String>,
60-
}
61-
6256
// Fully-resolved toolchain descriptors. These always have full target
6357
// triples attached to them and are used for canonical identification,
6458
// such as naming their installation directory.
@@ -73,50 +67,6 @@ pub struct ToolchainDesc {
7367
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
7468
pub struct TargetTriple(String);
7569

76-
// These lists contain the targets known to rustup, and used to build
77-
// the PartialTargetTriple.
78-
79-
static LIST_ARCHS: &[&str] = &[
80-
"i386",
81-
"i586",
82-
"i686",
83-
"x86_64",
84-
"arm",
85-
"armv7",
86-
"armv7s",
87-
"aarch64",
88-
"mips",
89-
"mipsel",
90-
"mips64",
91-
"mips64el",
92-
"powerpc",
93-
"powerpc64",
94-
"powerpc64le",
95-
"riscv64gc",
96-
"s390x",
97-
];
98-
static LIST_OSES: &[&str] = &[
99-
"pc-windows",
100-
"unknown-linux",
101-
"apple-darwin",
102-
"unknown-netbsd",
103-
"apple-ios",
104-
"linux",
105-
"rumprun-netbsd",
106-
"unknown-freebsd",
107-
"unknown-illumos",
108-
];
109-
static LIST_ENVS: &[&str] = &[
110-
"gnu",
111-
"msvc",
112-
"gnueabi",
113-
"gnueabihf",
114-
"gnuabi64",
115-
"androideabi",
116-
"android",
117-
"musl",
118-
];
119-
12070
// Linux hosts don't indicate clib in uname, however binaries only
12171
// run on boxes with the same clib, as expected.
12272
#[cfg(all(not(windows), not(target_env = "musl")))]
@@ -303,47 +253,6 @@ impl std::convert::TryFrom<PartialTargetTriple> for TargetTriple {
303253
}
304254
}
305255

306-
impl PartialTargetTriple {
307-
pub fn new(name: &str) -> Option<Self> {
308-
if name.is_empty() {
309-
return Some(Self {
310-
arch: None,
311-
os: None,
312-
env: None,
313-
});
314-
}
315-
316-
// Prepending `-` makes this next regex easier since
317-
// we can count on all triple components being
318-
// delineated by it.
319-
let name = format!("-{}", name);
320-
lazy_static! {
321-
static ref PATTERN: String = format!(
322-
r"^(?:-({}))?(?:-({}))?(?:-({}))?$",
323-
LIST_ARCHS.join("|"),
324-
LIST_OSES.join("|"),
325-
LIST_ENVS.join("|")
326-
);
327-
static ref RE: Regex = Regex::new(&PATTERN).unwrap();
328-
}
329-
RE.captures(&name).map(|c| {
330-
fn fn_map(s: &str) -> Option<String> {
331-
if s == "" {
332-
None
333-
} else {
334-
Some(s.to_owned())
335-
}
336-
}
337-
338-
Self {
339-
arch: c.get(1).map(|s| s.as_str()).and_then(fn_map),
340-
os: c.get(2).map(|s| s.as_str()).and_then(fn_map),
341-
env: c.get(3).map(|s| s.as_str()).and_then(fn_map),
342-
}
343-
})
344-
}
345-
}
346-
347256
impl FromStr for PartialToolchainDesc {
348257
type Err = Error;
349258
fn from_str(name: &str) -> Result<Self> {
@@ -1033,69 +942,6 @@ mod tests {
1033942
}
1034943
}
1035944

1036-
#[test]
1037-
fn test_partial_target_triple_new() {
1038-
let success_cases = vec![
1039-
("", (None, None, None)),
1040-
("i386", (Some("i386"), None, None)),
1041-
("pc-windows", (None, Some("pc-windows"), None)),
1042-
("gnu", (None, None, Some("gnu"))),
1043-
("i386-gnu", (Some("i386"), None, Some("gnu"))),
1044-
("pc-windows-gnu", (None, Some("pc-windows"), Some("gnu"))),
1045-
("i386-pc-windows", (Some("i386"), Some("pc-windows"), None)),
1046-
(
1047-
"i386-pc-windows-gnu",
1048-
(Some("i386"), Some("pc-windows"), Some("gnu")),
1049-
),
1050-
];
1051-
1052-
for (input, (arch, os, env)) in success_cases {
1053-
let partial_target_triple = PartialTargetTriple::new(input);
1054-
assert!(
1055-
partial_target_triple.is_some(),
1056-
"expected `{}` to create some partial target triple; got None",
1057-
input
1058-
);
1059-
1060-
let expected = PartialTargetTriple {
1061-
arch: arch.map(String::from),
1062-
os: os.map(String::from),
1063-
env: env.map(String::from),
1064-
};
1065-
1066-
assert_eq!(
1067-
partial_target_triple.unwrap(),
1068-
expected,
1069-
"input: `{}`",
1070-
input
1071-
);
1072-
}
1073-
1074-
let failure_cases = vec![
1075-
"anything",
1076-
"any-other-thing",
1077-
"-",
1078-
"--",
1079-
"i386-",
1080-
"i386-pc-",
1081-
"i386-pc-windows-",
1082-
"-pc-windows",
1083-
"i386-pc-windows-anything",
1084-
"0000-00-00-",
1085-
"00000-000-000",
1086-
];
1087-
1088-
for input in failure_cases {
1089-
let partial_target_triple = PartialTargetTriple::new(input);
1090-
assert!(
1091-
partial_target_triple.is_none(),
1092-
"expected `{}` to be `None`, was: `{:?}`",
1093-
input,
1094-
partial_target_triple
1095-
);
1096-
}
1097-
}
1098-
1099945
#[test]
1100946
fn test_tracking_channels() {
1101947
static CASES: &[(&str, bool)] = &[

src/dist/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ pub mod manifestation;
1414
pub mod notifications;
1515
pub mod prefix;
1616
pub mod signatures;
17+
pub mod triple;

src/dist/triple.rs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
use lazy_static::lazy_static;
2+
use regex::Regex;
3+
4+
// These lists contain the targets known to rustup, and used to build
5+
// the PartialTargetTriple.
6+
7+
static LIST_ARCHS: &[&str] = &[
8+
"i386",
9+
"i586",
10+
"i686",
11+
"x86_64",
12+
"arm",
13+
"armv7",
14+
"armv7s",
15+
"aarch64",
16+
"mips",
17+
"mipsel",
18+
"mips64",
19+
"mips64el",
20+
"powerpc",
21+
"powerpc64",
22+
"powerpc64le",
23+
"riscv64gc",
24+
"s390x",
25+
];
26+
static LIST_OSES: &[&str] = &[
27+
"pc-windows",
28+
"unknown-linux",
29+
"apple-darwin",
30+
"unknown-netbsd",
31+
"apple-ios",
32+
"linux",
33+
"rumprun-netbsd",
34+
"unknown-freebsd",
35+
"unknown-illumos",
36+
];
37+
static LIST_ENVS: &[&str] = &[
38+
"gnu",
39+
"msvc",
40+
"gnueabi",
41+
"gnueabihf",
42+
"gnuabi64",
43+
"androideabi",
44+
"android",
45+
"musl",
46+
];
47+
48+
#[derive(Debug, Clone, PartialEq, Eq)]
49+
pub struct PartialTargetTriple {
50+
pub arch: Option<String>,
51+
pub os: Option<String>,
52+
pub env: Option<String>,
53+
}
54+
55+
impl PartialTargetTriple {
56+
pub fn new(name: &str) -> Option<Self> {
57+
if name.is_empty() {
58+
return Some(Self {
59+
arch: None,
60+
os: None,
61+
env: None,
62+
});
63+
}
64+
65+
// Prepending `-` makes this next regex easier since
66+
// we can count on all triple components being
67+
// delineated by it.
68+
let name = format!("-{}", name);
69+
lazy_static! {
70+
static ref PATTERN: String = format!(
71+
r"^(?:-({}))?(?:-({}))?(?:-({}))?$",
72+
LIST_ARCHS.join("|"),
73+
LIST_OSES.join("|"),
74+
LIST_ENVS.join("|")
75+
);
76+
static ref RE: Regex = Regex::new(&PATTERN).unwrap();
77+
}
78+
RE.captures(&name).map(|c| {
79+
fn fn_map(s: &str) -> Option<String> {
80+
if s == "" {
81+
None
82+
} else {
83+
Some(s.to_owned())
84+
}
85+
}
86+
87+
Self {
88+
arch: c.get(1).map(|s| s.as_str()).and_then(fn_map),
89+
os: c.get(2).map(|s| s.as_str()).and_then(fn_map),
90+
env: c.get(3).map(|s| s.as_str()).and_then(fn_map),
91+
}
92+
})
93+
}
94+
}
95+
96+
#[cfg(test)]
97+
mod test {
98+
use super::*;
99+
#[test]
100+
fn test_partial_target_triple_new() {
101+
let success_cases = vec![
102+
("", (None, None, None)),
103+
("i386", (Some("i386"), None, None)),
104+
("pc-windows", (None, Some("pc-windows"), None)),
105+
("gnu", (None, None, Some("gnu"))),
106+
("i386-gnu", (Some("i386"), None, Some("gnu"))),
107+
("pc-windows-gnu", (None, Some("pc-windows"), Some("gnu"))),
108+
("i386-pc-windows", (Some("i386"), Some("pc-windows"), None)),
109+
(
110+
"i386-pc-windows-gnu",
111+
(Some("i386"), Some("pc-windows"), Some("gnu")),
112+
),
113+
];
114+
115+
for (input, (arch, os, env)) in success_cases {
116+
let partial_target_triple = PartialTargetTriple::new(input);
117+
assert!(
118+
partial_target_triple.is_some(),
119+
"expected `{}` to create some partial target triple; got None",
120+
input
121+
);
122+
123+
let expected = PartialTargetTriple {
124+
arch: arch.map(String::from),
125+
os: os.map(String::from),
126+
env: env.map(String::from),
127+
};
128+
129+
assert_eq!(
130+
partial_target_triple.unwrap(),
131+
expected,
132+
"input: `{}`",
133+
input
134+
);
135+
}
136+
137+
let failure_cases = vec![
138+
"anything",
139+
"any-other-thing",
140+
"-",
141+
"--",
142+
"i386-",
143+
"i386-pc-",
144+
"i386-pc-windows-",
145+
"-pc-windows",
146+
"i386-pc-windows-anything",
147+
"0000-00-00-",
148+
"00000-000-000",
149+
];
150+
151+
for input in failure_cases {
152+
let partial_target_triple = PartialTargetTriple::new(input);
153+
assert!(
154+
partial_target_triple.is_none(),
155+
"expected `{}` to be `None`, was: `{:?}`",
156+
input,
157+
partial_target_triple
158+
);
159+
}
160+
}
161+
}

0 commit comments

Comments
 (0)