@@ -1463,85 +1463,7 @@ impl GlobalContext {
14631463 self . _load_file ( & self . cwd ( ) . join ( & str_path) , & mut seen, true , WhyLoad :: Cli )
14641464 . with_context ( || format ! ( "failed to load config from `{}`" , str_path) ) ?
14651465 } else {
1466- // We only want to allow "dotted key" (see https://toml.io/en/v1.0.0#keys)
1467- // expressions followed by a value that's not an "inline table"
1468- // (https://toml.io/en/v1.0.0#inline-table). Easiest way to check for that is to
1469- // parse the value as a toml_edit::DocumentMut, and check that the (single)
1470- // inner-most table is set via dotted keys.
1471- let doc: toml_edit:: DocumentMut = arg. parse ( ) . with_context ( || {
1472- format ! ( "failed to parse value from --config argument `{arg}` as a dotted key expression" )
1473- } ) ?;
1474- fn non_empty ( d : Option < & toml_edit:: RawString > ) -> bool {
1475- d. map_or ( false , |p| !p. as_str ( ) . unwrap_or_default ( ) . trim ( ) . is_empty ( ) )
1476- }
1477- fn non_empty_decor ( d : & toml_edit:: Decor ) -> bool {
1478- non_empty ( d. prefix ( ) ) || non_empty ( d. suffix ( ) )
1479- }
1480- fn non_empty_key_decor ( k : & toml_edit:: Key ) -> bool {
1481- non_empty_decor ( k. leaf_decor ( ) ) || non_empty_decor ( k. dotted_decor ( ) )
1482- }
1483- let ok = {
1484- let mut got_to_value = false ;
1485- let mut table = doc. as_table ( ) ;
1486- let mut is_root = true ;
1487- while table. is_dotted ( ) || is_root {
1488- is_root = false ;
1489- if table. len ( ) != 1 {
1490- break ;
1491- }
1492- let ( k, n) = table. iter ( ) . next ( ) . expect ( "len() == 1 above" ) ;
1493- match n {
1494- Item :: Table ( nt) => {
1495- if table. key ( k) . map_or ( false , non_empty_key_decor)
1496- || non_empty_decor ( nt. decor ( ) )
1497- {
1498- bail ! (
1499- "--config argument `{arg}` \
1500- includes non-whitespace decoration"
1501- )
1502- }
1503- table = nt;
1504- }
1505- Item :: Value ( v) if v. is_inline_table ( ) => {
1506- bail ! (
1507- "--config argument `{arg}` \
1508- sets a value to an inline table, which is not accepted"
1509- ) ;
1510- }
1511- Item :: Value ( v) => {
1512- if table
1513- . key ( k)
1514- . map_or ( false , |k| non_empty ( k. leaf_decor ( ) . prefix ( ) ) )
1515- || non_empty_decor ( v. decor ( ) )
1516- {
1517- bail ! (
1518- "--config argument `{arg}` \
1519- includes non-whitespace decoration"
1520- )
1521- }
1522- got_to_value = true ;
1523- break ;
1524- }
1525- Item :: ArrayOfTables ( _) => {
1526- bail ! (
1527- "--config argument `{arg}` \
1528- sets a value to an array of tables, which is not accepted"
1529- ) ;
1530- }
1531-
1532- Item :: None => {
1533- bail ! ( "--config argument `{arg}` doesn't provide a value" )
1534- }
1535- }
1536- }
1537- got_to_value
1538- } ;
1539- if !ok {
1540- bail ! (
1541- "--config argument `{arg}` was not a TOML dotted key expression (such as `build.jobs = 2`)"
1542- ) ;
1543- }
1544-
1466+ let doc = toml_dotted_keys ( arg) ?;
15451467 let toml_v: toml:: Value = toml:: Value :: deserialize ( doc. into_deserializer ( ) )
15461468 . with_context ( || {
15471469 format ! ( "failed to parse value from --config argument `{arg}`" )
@@ -3046,6 +2968,88 @@ fn parse_document(toml: &str, _file: &Path, _gctx: &GlobalContext) -> CargoResul
30462968 toml. parse ( ) . map_err ( Into :: into)
30472969}
30482970
2971+ fn toml_dotted_keys ( arg : & str ) -> CargoResult < toml_edit:: DocumentMut > {
2972+ // We only want to allow "dotted key" (see https://toml.io/en/v1.0.0#keys)
2973+ // expressions followed by a value that's not an "inline table"
2974+ // (https://toml.io/en/v1.0.0#inline-table). Easiest way to check for that is to
2975+ // parse the value as a toml_edit::DocumentMut, and check that the (single)
2976+ // inner-most table is set via dotted keys.
2977+ let doc: toml_edit:: DocumentMut = arg. parse ( ) . with_context ( || {
2978+ format ! ( "failed to parse value from --config argument `{arg}` as a dotted key expression" )
2979+ } ) ?;
2980+ fn non_empty ( d : Option < & toml_edit:: RawString > ) -> bool {
2981+ d. map_or ( false , |p| !p. as_str ( ) . unwrap_or_default ( ) . trim ( ) . is_empty ( ) )
2982+ }
2983+ fn non_empty_decor ( d : & toml_edit:: Decor ) -> bool {
2984+ non_empty ( d. prefix ( ) ) || non_empty ( d. suffix ( ) )
2985+ }
2986+ fn non_empty_key_decor ( k : & toml_edit:: Key ) -> bool {
2987+ non_empty_decor ( k. leaf_decor ( ) ) || non_empty_decor ( k. dotted_decor ( ) )
2988+ }
2989+ let ok = {
2990+ let mut got_to_value = false ;
2991+ let mut table = doc. as_table ( ) ;
2992+ let mut is_root = true ;
2993+ while table. is_dotted ( ) || is_root {
2994+ is_root = false ;
2995+ if table. len ( ) != 1 {
2996+ break ;
2997+ }
2998+ let ( k, n) = table. iter ( ) . next ( ) . expect ( "len() == 1 above" ) ;
2999+ match n {
3000+ Item :: Table ( nt) => {
3001+ if table. key ( k) . map_or ( false , non_empty_key_decor)
3002+ || non_empty_decor ( nt. decor ( ) )
3003+ {
3004+ bail ! (
3005+ "--config argument `{arg}` \
3006+ includes non-whitespace decoration"
3007+ )
3008+ }
3009+ table = nt;
3010+ }
3011+ Item :: Value ( v) if v. is_inline_table ( ) => {
3012+ bail ! (
3013+ "--config argument `{arg}` \
3014+ sets a value to an inline table, which is not accepted"
3015+ ) ;
3016+ }
3017+ Item :: Value ( v) => {
3018+ if table
3019+ . key ( k)
3020+ . map_or ( false , |k| non_empty ( k. leaf_decor ( ) . prefix ( ) ) )
3021+ || non_empty_decor ( v. decor ( ) )
3022+ {
3023+ bail ! (
3024+ "--config argument `{arg}` \
3025+ includes non-whitespace decoration"
3026+ )
3027+ }
3028+ got_to_value = true ;
3029+ break ;
3030+ }
3031+ Item :: ArrayOfTables ( _) => {
3032+ bail ! (
3033+ "--config argument `{arg}` \
3034+ sets a value to an array of tables, which is not accepted"
3035+ ) ;
3036+ }
3037+
3038+ Item :: None => {
3039+ bail ! ( "--config argument `{arg}` doesn't provide a value" )
3040+ }
3041+ }
3042+ }
3043+ got_to_value
3044+ } ;
3045+ if !ok {
3046+ bail ! (
3047+ "--config argument `{arg}` was not a TOML dotted key expression (such as `build.jobs = 2`)"
3048+ ) ;
3049+ }
3050+ Ok ( doc)
3051+ }
3052+
30493053/// A type to deserialize a list of strings from a toml file.
30503054///
30513055/// Supports deserializing either a whitespace-separated list of arguments in a
0 commit comments