From 728d143e26b084f08eff74a8c6d266c2f741ba46 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 9 Nov 2022 23:50:29 +0000 Subject: [PATCH] validate implicit flag names --- argh/tests/ui/bad-long-names/bad-long-names.rs | 15 +++++++++++++++ .../ui/bad-long-names/bad-long-names.stderr | 17 +++++++++++++++++ argh_derive/src/lib.rs | 12 ++++++------ argh_derive/src/parse_attrs.rs | 16 ++++++++++------ 4 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 argh/tests/ui/bad-long-names/bad-long-names.rs create mode 100644 argh/tests/ui/bad-long-names/bad-long-names.stderr diff --git a/argh/tests/ui/bad-long-names/bad-long-names.rs b/argh/tests/ui/bad-long-names/bad-long-names.rs new file mode 100644 index 0000000..61a9696 --- /dev/null +++ b/argh/tests/ui/bad-long-names/bad-long-names.rs @@ -0,0 +1,15 @@ +/// Command +#[derive(argh::FromArgs)] +struct Cmd { + #[argh(switch)] + /// non-ascii + привет: bool, + #[argh(switch)] + /// uppercase + XMLHTTPRequest: bool, + #[argh(switch, long = "not really")] + /// bad attr + ok: bool, +} + +fn main() {} diff --git a/argh/tests/ui/bad-long-names/bad-long-names.stderr b/argh/tests/ui/bad-long-names/bad-long-names.stderr new file mode 100644 index 0000000..3396a5a --- /dev/null +++ b/argh/tests/ui/bad-long-names/bad-long-names.stderr @@ -0,0 +1,17 @@ +error: Long names must be ASCII + --> tests/ui/bad-long-names/bad-long-names.rs:6:5 + | +6 | привет: bool, + | ^^^^^^ + +error: Long names must be lowercase + --> tests/ui/bad-long-names/bad-long-names.rs:9:5 + | +9 | XMLHTTPRequest: bool, + | ^^^^^^^^^^^^^^ + +error: Long names must be lowercase + --> tests/ui/bad-long-names/bad-long-names.rs:10:27 + | +10 | #[argh(switch, long = "not really")] + | ^^^^^^^^^^^^ diff --git a/argh_derive/src/lib.rs b/argh_derive/src/lib.rs index aed5e3b..94cc437 100644 --- a/argh_derive/src/lib.rs +++ b/argh_derive/src/lib.rs @@ -11,7 +11,7 @@ extern crate proc_macro; use { crate::{ errors::Errors, - parse_attrs::{FieldAttrs, FieldKind, TypeAttrs}, + parse_attrs::{check_long_name, FieldAttrs, FieldKind, TypeAttrs}, }, proc_macro2::{Span, TokenStream}, quote::{quote, quote_spanned, ToTokens}, @@ -178,11 +178,11 @@ impl<'a> StructField<'a> { // Defaults to the kebab-case'd field name if `#[argh(long = "...")]` is omitted. let long_name = match kind { FieldKind::Switch | FieldKind::Option => { - let long_name = attrs - .long - .as_ref() - .map(syn::LitStr::value) - .unwrap_or_else(|| to_kebab_case(&name.to_string())); + let long_name = attrs.long.as_ref().map(syn::LitStr::value).unwrap_or_else(|| { + let kebab_name = to_kebab_case(&name.to_string()); + check_long_name(errors, name, &kebab_name); + kebab_name + }); if long_name == "help" { errors.err(field, "Custom `--help` flags are not supported."); } diff --git a/argh_derive/src/parse_attrs.rs b/argh_derive/src/parse_attrs.rs index 0d1cca3..04dcbdd 100644 --- a/argh_derive/src/parse_attrs.rs +++ b/argh_derive/src/parse_attrs.rs @@ -183,12 +183,7 @@ impl FieldAttrs { parse_attr_single_string(errors, m, "long", &mut self.long); let long = self.long.as_ref().unwrap(); let value = long.value(); - if !value.is_ascii() { - errors.err(long, "Long names must be ASCII"); - } - if !value.chars().all(|c| c.is_lowercase() || c == '-' || c.is_ascii_digit()) { - errors.err(long, "Long names must be lowercase"); - } + check_long_name(errors, long, &value); } fn parse_attr_short(&mut self, errors: &Errors, m: &syn::MetaNameValue) { @@ -203,6 +198,15 @@ impl FieldAttrs { } } +pub(crate) fn check_long_name(errors: &Errors, spanned: &impl syn::spanned::Spanned, value: &str) { + if !value.is_ascii() { + errors.err(spanned, "Long names must be ASCII"); + } + if !value.chars().all(|c| c.is_lowercase() || c == '-' || c.is_ascii_digit()) { + errors.err(spanned, "Long names must be lowercase"); + } +} + fn parse_attr_fn_name( errors: &Errors, m: &syn::MetaList,