Skip to content

Commit c1b7511

Browse files
committed
Reject colons in target specs
1 parent e4f7cab commit c1b7511

File tree

4 files changed

+69
-8
lines changed

4 files changed

+69
-8
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313

1414
### Changed
1515

16+
* `only`/`ignore` filters now only accept integers, alphabetic characters, `-` and `_`
17+
1618
### Removed
1719

1820
## [0.26.4] - 2024-09-09

src/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,8 @@ impl Config {
395395
let target = self.target.as_ref().unwrap();
396396
match condition {
397397
Condition::Bitwidth(bits) => bits.iter().any(|bits| self.get_pointer_width() == *bits),
398-
Condition::Target(t) => t.iter().any(|t| target.contains(t)),
399-
Condition::Host(t) => t.iter().any(|t| self.host.as_ref().unwrap().contains(t)),
398+
Condition::Target(t) => t.iter().any(|t| target.contains(&**t)),
399+
Condition::Host(t) => t.iter().any(|t| self.host.as_ref().unwrap().contains(&**t)),
400400
Condition::OnHost => self.host_matches_target(),
401401
}
402402
}

src/parser.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,15 +225,51 @@ impl<T> std::ops::DerefMut for CommentParser<T> {
225225
#[derive(Debug, Clone)]
226226
pub enum Condition {
227227
/// One of the given strings must appear in the host triple.
228-
Host(Vec<String>),
228+
Host(Vec<TargetSubStr>),
229229
/// One of the given string must appear in the target triple.
230-
Target(Vec<String>),
230+
Target(Vec<TargetSubStr>),
231231
/// Tests that the bitwidth is one of the given ones.
232232
Bitwidth(Vec<u8>),
233233
/// Tests that the target is the host.
234234
OnHost,
235235
}
236236

237+
#[derive(Debug, Clone)]
238+
/// A sub string of a target (or a whole target).
239+
/// Effectively a `String` that only allows lowercase chars, integers and dashes
240+
pub struct TargetSubStr(String);
241+
242+
impl PartialEq<&str> for TargetSubStr {
243+
fn eq(&self, other: &&str) -> bool {
244+
self.0 == *other
245+
}
246+
}
247+
248+
impl std::ops::Deref for TargetSubStr {
249+
type Target = str;
250+
251+
fn deref(&self) -> &Self::Target {
252+
&self.0
253+
}
254+
}
255+
256+
impl TryFrom<String> for TargetSubStr {
257+
type Error = String;
258+
259+
fn try_from(value: String) -> std::result::Result<Self, Self::Error> {
260+
if value
261+
.chars()
262+
.all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_')
263+
{
264+
Ok(Self(value))
265+
} else {
266+
Err(format!(
267+
"target strings can only contain integers, basic alphabet characters or dashes"
268+
))
269+
}
270+
}
271+
}
272+
237273
#[derive(Debug, Clone)]
238274
/// An error pattern parsed from a `//~` comment.
239275
pub enum Pattern {
@@ -270,8 +306,8 @@ impl Condition {
270306
})).collect::<Result<Vec<_>, _>>()?;
271307
Ok(Condition::Bitwidth(bits))
272308
}
273-
"target" => Ok(Condition::Target(args.map(|arg|arg.to_owned()).collect())),
274-
"host" => Ok(Condition::Host(args.map(|arg|arg.to_owned()).collect())),
309+
"target" => Ok(Condition::Target(args.map(|arg|TargetSubStr::try_from(arg.to_owned())).collect::<Result<_, _>>()?)),
310+
"host" => Ok(Condition::Host(args.map(|arg|TargetSubStr::try_from(arg.to_owned())).collect::<Result<_, _>>()?)),
275311
_ => Err(format!("`{c}` is not a valid condition, expected `on-host`, /[0-9]+bit/, /host-.*/, or /target-.*/")),
276312
}
277313
}

src/parser/tests.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,10 @@ fn parse_x86_64() {
255255
let revisioned = &comments.revisioned[&vec![]];
256256
assert_eq!(revisioned.only.len(), 1);
257257
match &revisioned.only[0] {
258-
Condition::Target(t) => assert_eq!(t, &["x86_64-unknown-linux"]),
258+
Condition::Target(t) => {
259+
assert_eq!(t.len(), 1);
260+
assert_eq!(t[0], "x86_64-unknown-linux")
261+
}
259262
_ => unreachable!(),
260263
}
261264
}
@@ -279,7 +282,27 @@ fn parse_two_only_filters() {
279282
let revisioned = &comments.revisioned[&vec![]];
280283
assert_eq!(revisioned.only.len(), 1);
281284
match &revisioned.only[0] {
282-
Condition::Target(t) => assert_eq!(t, &["hello", "world"]),
285+
Condition::Target(t) => {
286+
assert_eq!(t.len(), 2);
287+
assert_eq!(t[0], "hello");
288+
assert_eq!(t[1], "world")
289+
}
283290
_ => unreachable!(),
284291
}
285292
}
293+
294+
#[test]
295+
fn parse_invalid_filter() {
296+
let s = r"//@only-target: hello world: somecomment";
297+
Comments::parse(
298+
Spanned::new(
299+
s.as_bytes(),
300+
Span {
301+
file: PathBuf::new(),
302+
bytes: 0..s.len(),
303+
},
304+
),
305+
&Config::dummy(),
306+
)
307+
.unwrap_err();
308+
}

0 commit comments

Comments
 (0)