From 4e5c550890d06480fafabd720fb93d8c54e0cdd3 Mon Sep 17 00:00:00 2001 From: pickx Date: Mon, 17 Jul 2023 17:58:44 +0300 Subject: [PATCH] validate macro input --- bilge-impl/src/bitsize.rs | 15 ++------------- bilge-impl/src/fmt_bits.rs | 7 +------ bilge-impl/src/from_bits.rs | 7 +------ bilge-impl/src/lib.rs | 33 +++++++++++++++++++++++---------- bilge-impl/src/shared.rs | 4 ++++ bilge-impl/src/try_from_bits.rs | 7 +------ 6 files changed, 32 insertions(+), 41 deletions(-) diff --git a/bilge-impl/src/bitsize.rs b/bilge-impl/src/bitsize.rs index 752f5d7..d901ca2 100644 --- a/bilge-impl/src/bitsize.rs +++ b/bilge-impl/src/bitsize.rs @@ -13,8 +13,8 @@ struct ItemIr { expanded: TokenStream, } -pub(super) fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream { - let (item, declared_bitsize) = parse(item, args); +pub(super) fn bitsize(args: TokenStream, item: Item) -> TokenStream { + let (declared_bitsize, _arb_int) = shared::bitsize_and_arbitrary_int_from(args); let attrs = SplitAttributes::from_item(&item); let ir = match item { Item::Struct(mut item) => { @@ -33,17 +33,6 @@ pub(super) fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream { generate_common(ir, attrs, declared_bitsize) } -fn parse(item: TokenStream, args: TokenStream) -> (Item, BitSize) { - let item = syn::parse2(item).unwrap_or_else(unreachable); - - if args.is_empty() { - abort_call_site!("missing attribute value"; help = "you need to define the size like this: `#[bitsize(32)]`") - } - - let (declared_bitsize, _arb_int) = shared::bitsize_and_arbitrary_int_from(args); - (item, declared_bitsize) -} - fn check_type_is_supported(ty: &Type) { use Type::*; match ty { diff --git a/bilge-impl/src/fmt_bits.rs b/bilge-impl/src/fmt_bits.rs index fde6cc1..a98699d 100644 --- a/bilge-impl/src/fmt_bits.rs +++ b/bilge-impl/src/fmt_bits.rs @@ -3,8 +3,7 @@ use proc_macro2::{Ident, TokenStream}; use quote::quote; use syn::{Data, DeriveInput, Fields, Variant, punctuated::Iter}; -pub(crate) fn binary(item: TokenStream) -> TokenStream { - let derive_input = parse(item); +pub(crate) fn binary(derive_input: DeriveInput) -> TokenStream { let (derive_data, arb_int, name, bitsize, ..) = analyze(&derive_input); match derive_data { @@ -86,10 +85,6 @@ fn generate_to_int_match_arms(variants: Iter, enum_name: &Ident, bitsiz .collect() } -fn parse(item: TokenStream) -> DeriveInput { - shared::parse_derive(item) -} - fn analyze(derive_input: &DeriveInput) -> (&Data, TokenStream, &Ident, BitSize, Option) { shared::analyze_derive(derive_input, false) } diff --git a/bilge-impl/src/from_bits.rs b/bilge-impl/src/from_bits.rs index daf699c..385f0d3 100644 --- a/bilge-impl/src/from_bits.rs +++ b/bilge-impl/src/from_bits.rs @@ -5,8 +5,7 @@ use quote::quote; use syn::{Type, Fields, DeriveInput, Data, punctuated::Iter, Variant}; use crate::shared::{fallback::Fallback, self, BitSize, unreachable, discriminant_assigner::DiscriminantAssigner, enum_fills_bitsize}; -pub(super) fn from_bits(item: TokenStream) -> TokenStream { - let derive_input = parse(item); +pub(super) fn from_bits(derive_input: DeriveInput) -> TokenStream { let (derive_data, arb_int, name, internal_bitsize, fallback) = analyze(&derive_input); let expanded = match &derive_data { Data::Struct(struct_data) => { @@ -22,10 +21,6 @@ pub(super) fn from_bits(item: TokenStream) -> TokenStream { generate_common(expanded) } -fn parse(item: TokenStream) -> DeriveInput { - shared::parse_derive(item) -} - fn analyze(derive_input: &DeriveInput) -> (&syn::Data, TokenStream, &Ident, BitSize, Option) { shared::analyze_derive(derive_input, false) } diff --git a/bilge-impl/src/lib.rs b/bilge-impl/src/lib.rs index f6aa1a6..fc1be09 100644 --- a/bilge-impl/src/lib.rs +++ b/bilge-impl/src/lib.rs @@ -1,5 +1,6 @@ use proc_macro::TokenStream; use proc_macro_error::proc_macro_error; +use syn::parse_macro_input; mod bitsize; mod bitsize_internal; @@ -19,7 +20,9 @@ mod shared; #[proc_macro_error] #[proc_macro_attribute] pub fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream { - bitsize::bitsize(args.into(), item.into()).into() + let item = parse_macro_input!(item); + + bitsize::bitsize(args.into(), item).into() } /// This is internally used, not to be used by anything besides `bitsize`. @@ -27,7 +30,9 @@ pub fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro_error] #[proc_macro_attribute] pub fn bitsize_internal(args: TokenStream, item: TokenStream) -> TokenStream { - bitsize_internal::bitsize_internal(args.into(), item.into()).into() + let item = parse_macro_input!(item); + + bitsize_internal::bitsize_internal(args.into(), item).into() } /// Generate an `impl TryFrom` for unfilled bitfields. @@ -36,8 +41,10 @@ pub fn bitsize_internal(args: TokenStream, item: TokenStream) -> TokenStream { /// a struct don't fill their given `bitsize`. #[proc_macro_error] #[proc_macro_derive(TryFromBits, attributes(bitsize_internal, fallback))] -pub fn derive_try_from_bits(item: TokenStream) -> TokenStream { - try_from_bits::try_from_bits(item.into()).into() +pub fn derive_try_from_bits(derive_input: TokenStream) -> TokenStream { + let derive_input = parse_macro_input!(derive_input); + + try_from_bits::try_from_bits(derive_input).into() } /// Generate an `impl From` for filled bitfields. @@ -47,8 +54,10 @@ pub fn derive_try_from_bits(item: TokenStream) -> TokenStream { /// using enums. #[proc_macro_error] #[proc_macro_derive(FromBits, attributes(bitsize_internal, fallback))] -pub fn derive_from_bits(item: TokenStream) -> TokenStream { - from_bits::from_bits(item.into()).into() +pub fn derive_from_bits(derive_input: TokenStream) -> TokenStream { + let derive_input = parse_macro_input!(derive_input); + + from_bits::from_bits(derive_input).into() } /// Generate an `impl Debug` for bitfield structs. @@ -56,13 +65,17 @@ pub fn derive_from_bits(item: TokenStream) -> TokenStream { /// Please use normal #[derive(Debug)] for enums. #[proc_macro_error] #[proc_macro_derive(DebugBits, attributes(bitsize_internal))] -pub fn debug_bits(item: TokenStream) -> TokenStream { - debug_bits::debug_bits(item.into()).into() +pub fn debug_bits(derive_input: TokenStream) -> TokenStream { + let derive_input = parse_macro_input!(derive_input); + + debug_bits::debug_bits(derive_input).into() } /// Generate an `impl core::fmt::Binary` for bitfields. #[proc_macro_error] #[proc_macro_derive(BinaryBits)] -pub fn derive_binary_bits(item: TokenStream) -> TokenStream { - fmt_bits::binary(item.into()).into() +pub fn derive_binary_bits(derive_input: TokenStream) -> TokenStream { + let derive_input = parse_macro_input!(derive_input); + + fmt_bits::binary(derive_input).into() } \ No newline at end of file diff --git a/bilge-impl/src/shared.rs b/bilge-impl/src/shared.rs index f8f11f6..2b97ca5 100644 --- a/bilge-impl/src/shared.rs +++ b/bilge-impl/src/shared.rs @@ -67,6 +67,10 @@ pub(crate) fn analyze_derive(derive_input: &DeriveInput, try_from: bool) -> (&sy // If we want to support bitsize(u4) besides bitsize(4), do that here. pub fn bitsize_and_arbitrary_int_from(bitsize_arg: TokenStream) -> (BitSize, TokenStream) { + if bitsize_arg.is_empty() { + abort_call_site!("missing attribute value"; help = "you need to define the size like this: `#[bitsize(32)]`") + } + let bitsize: LitInt = syn::parse2(bitsize_arg.clone()).unwrap_or_else(|_| abort!(bitsize_arg, "attribute value is not a number"; help = "you need to define the size like this: `#[bitsize(32)]`") ); diff --git a/bilge-impl/src/try_from_bits.rs b/bilge-impl/src/try_from_bits.rs index e028c9d..064757e 100644 --- a/bilge-impl/src/try_from_bits.rs +++ b/bilge-impl/src/try_from_bits.rs @@ -5,8 +5,7 @@ use syn::{DeriveInput, Data, punctuated::Iter, Variant, Type, Fields}; use crate::shared::{last_ident_of_path, bitsize_from_type_ident}; use crate::shared::{fallback::Fallback, self, BitSize, unreachable, enum_fills_bitsize, discriminant_assigner::DiscriminantAssigner}; -pub(super) fn try_from_bits(item: TokenStream) -> TokenStream { - let derive_input = parse(item); +pub(super) fn try_from_bits(derive_input: DeriveInput) -> TokenStream { let (derive_data, arb_int, name, internal_bitsize, ..) = analyze(&derive_input); match derive_data { Data::Struct(ref data) => { @@ -21,10 +20,6 @@ pub(super) fn try_from_bits(item: TokenStream) -> TokenStream { } } -fn parse(item: TokenStream) -> DeriveInput { - shared::parse_derive(item) -} - fn analyze(derive_input: &DeriveInput) -> (&syn::Data, TokenStream, &Ident, BitSize, Option) { shared::analyze_derive(derive_input, true) }