Skip to content

Commit 51917b4

Browse files
author
Jon Gjengset
committed
Enforce no decorators in --config values
1 parent c4f4e20 commit 51917b4

File tree

2 files changed

+73
-15
lines changed

2 files changed

+73
-15
lines changed

src/cargo/util/config/mod.rs

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ use cargo_util::paths;
7979
use curl::easy::Easy;
8080
use lazycell::LazyCell;
8181
use serde::Deserialize;
82-
use toml_edit::easy as toml;
82+
use toml_edit::{easy as toml, Item};
8383
use url::Url;
8484

8585
mod de;
@@ -1184,6 +1184,10 @@ impl Config {
11841184
let doc: toml_edit::Document = arg.parse().with_context(|| {
11851185
format!("failed to parse value from --config argument `{}` as a dotted key expression", arg)
11861186
})?;
1187+
fn non_empty_decor(d: &toml_edit::Decor) -> bool {
1188+
d.prefix().map_or(false, |p| !p.trim().is_empty())
1189+
|| d.suffix().map_or(false, |s| !s.trim().is_empty())
1190+
}
11871191
let ok = {
11881192
let mut got_to_value = false;
11891193
let mut table = doc.as_table();
@@ -1193,17 +1197,49 @@ impl Config {
11931197
if table.len() != 1 {
11941198
break;
11951199
}
1196-
let (_, n) = table.iter().next().expect("len() == 1 above");
1197-
if let Some(nt) = n.as_table() {
1198-
table = nt;
1199-
} else if n.is_inline_table() {
1200-
bail!(
1201-
"--config argument `{}` sets a value to an inline table, which is not accepted",
1202-
arg,
1203-
);
1204-
} else {
1205-
got_to_value = true;
1206-
break;
1200+
let (k, n) = table.iter().next().expect("len() == 1 above");
1201+
match n {
1202+
Item::Table(nt) => {
1203+
if table.key_decor(k).map_or(false, non_empty_decor)
1204+
|| non_empty_decor(nt.decor())
1205+
{
1206+
bail!(
1207+
"--config argument `{}` \
1208+
includes non-whitespace decoration",
1209+
arg
1210+
)
1211+
}
1212+
table = nt;
1213+
}
1214+
Item::Value(v) if v.is_inline_table() => {
1215+
bail!(
1216+
"--config argument `{}` \
1217+
sets a value to an inline table, which is not accepted",
1218+
arg,
1219+
);
1220+
}
1221+
Item::Value(v) => {
1222+
if non_empty_decor(v.decor()) {
1223+
bail!(
1224+
"--config argument `{}` \
1225+
includes non-whitespace decoration",
1226+
arg
1227+
)
1228+
}
1229+
got_to_value = true;
1230+
break;
1231+
}
1232+
Item::ArrayOfTables(_) => {
1233+
bail!(
1234+
"--config argument `{}` \
1235+
sets a value to an array of tables, which is not accepted",
1236+
arg,
1237+
);
1238+
}
1239+
1240+
Item::None => {
1241+
bail!("--config argument `{}` doesn't provide a value", arg)
1242+
}
12071243
}
12081244
}
12091245
got_to_value

tests/testsuite/config_cli.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ Expected `.` or `=`
352352
let config = ConfigBuilder::new().config_arg("").build_err();
353353
assert_error(
354354
config.unwrap_err(),
355-
"--config argument `` was not a TOML dotted key expression (a.b.c = _)",
355+
"--config argument `` was not a TOML dotted key expression (such as `build.jobs = 2`)",
356356
);
357357
}
358358

@@ -364,7 +364,7 @@ fn too_many_values() {
364364
config.unwrap_err(),
365365
"\
366366
--config argument `a=1
367-
b=2` was not a TOML dotted key expression (a.b.c = _)",
367+
b=2` was not a TOML dotted key expression (such as `build.jobs = 2`)",
368368
);
369369
}
370370

@@ -390,7 +390,29 @@ fn no_array_of_tables_values() {
390390
config.unwrap_err(),
391391
"\
392392
--config argument `[[a.b]]
393-
c = \"d\"` was not a TOML dotted key expression (a.b.c = _)",
393+
c = \"d\"` was not a TOML dotted key expression (such as `build.jobs = 2`)",
394+
);
395+
}
396+
397+
#[cargo_test]
398+
fn no_comments() {
399+
// Disallow comments in dotted form.
400+
let config = ConfigBuilder::new()
401+
.config_arg("a.b = \"c\" # exactly")
402+
.build_err();
403+
assert_error(
404+
config.unwrap_err(),
405+
"\
406+
--config argument `a.b = \"c\" # exactly` includes non-whitespace decoration",
407+
);
408+
409+
let config = ConfigBuilder::new()
410+
.config_arg("# exactly\na.b = \"c\"")
411+
.build_err();
412+
assert_error(
413+
config.unwrap_err(),
414+
"\
415+
--config argument `# exactly\na.b = \"c\"` includes non-whitespace decoration",
394416
);
395417
}
396418

0 commit comments

Comments
 (0)