Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 39199bb

Browse files
committed
Use syn::Error to enforce whitelisted attributes on genesis config.
1 parent 8749bb4 commit 39199bb

File tree

2 files changed

+27
-13
lines changed

2 files changed

+27
-13
lines changed

srml/support/procedural/src/storage/genesis_config/genesis_config_def.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
1919
use srml_support_procedural_tools::syn_ext as ext;
2020
use proc_macro2::TokenStream;
21-
use syn::parse_quote;
21+
use syn::{spanned::Spanned, parse_quote};
2222
use quote::quote;
2323
use super::super::{DeclStorageDefExt, StorageLineTypeDef};
2424

@@ -43,8 +43,8 @@ pub struct GenesisConfigDef {
4343
}
4444

4545
impl GenesisConfigDef {
46-
pub fn from_def(def: &DeclStorageDefExt) -> Self {
47-
let fields = Self::get_genesis_config_field_defs(def);
46+
pub fn from_def(def: &DeclStorageDefExt) -> syn::Result<Self> {
47+
let fields = Self::get_genesis_config_field_defs(def)?;
4848

4949
let is_generic = fields.iter()
5050
.any(|field| ext::type_contains_ident(&field.typ, &def.module_runtime_generic));
@@ -71,17 +71,19 @@ impl GenesisConfigDef {
7171
(quote!(), quote!(), quote!(), None)
7272
};
7373

74-
Self {
74+
Ok(Self {
7575
is_generic,
7676
fields,
7777
genesis_struct_decl,
7878
genesis_struct,
7979
genesis_impl,
8080
genesis_where_clause,
81-
}
81+
})
8282
}
8383

84-
fn get_genesis_config_field_defs(def: &DeclStorageDefExt) -> Vec<GenesisConfigFieldDef> {
84+
fn get_genesis_config_field_defs(def: &DeclStorageDefExt)
85+
-> syn::Result<Vec<GenesisConfigFieldDef>>
86+
{
8587
let mut config_field_defs = Vec::new();
8688

8789
for (config_field, line) in def.storage_lines.iter()
@@ -123,9 +125,18 @@ impl GenesisConfigDef {
123125

124126
for line in &def.extra_genesis_config_lines {
125127
let attrs = line.attrs.iter()
126-
.filter_map(|a| a.parse_meta().ok())
127-
.filter(|m| m.path().is_ident("doc") || m.path().is_ident("serde"))
128-
.collect();
128+
.map(|attr| {
129+
let meta = attr.parse_meta()?;
130+
if meta.path().is_ident("doc") || meta.path().is_ident("serde") {
131+
Ok(meta)
132+
} else {
133+
Err(syn::Error::new(
134+
meta.span(),
135+
"extra genesis config item only supports `doc` and `serde` attributes"
136+
))
137+
}
138+
})
139+
.collect::<syn::Result<_>>()?;
129140

130141
let default = line.default.as_ref().map(|e| quote!( #e ))
131142
.unwrap_or_else(|| quote!( Default::default() ));
@@ -139,6 +150,6 @@ impl GenesisConfigDef {
139150
});
140151
}
141152

142-
config_field_defs
153+
Ok(config_field_defs)
143154
}
144155
}

srml/support/procedural/src/storage/genesis_config/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,13 @@ pub fn genesis_config_and_build_storage(
188188
) -> TokenStream {
189189
let builders = BuilderDef::from_def(scrate, def);
190190
if !builders.blocks.is_empty() {
191-
let genesis_config = &GenesisConfigDef::from_def(def);
191+
let genesis_config = match GenesisConfigDef::from_def(def) {
192+
Ok(genesis_config) => genesis_config,
193+
Err(err) => return err.to_compile_error(),
194+
};
192195
let decl_genesis_config_and_impl_default =
193-
decl_genesis_config_and_impl_default(scrate, genesis_config);
194-
let impl_build_storage = impl_build_storage(scrate, def, genesis_config, &builders);
196+
decl_genesis_config_and_impl_default(scrate, &genesis_config);
197+
let impl_build_storage = impl_build_storage(scrate, def, &genesis_config, &builders);
195198

196199
quote!{
197200
#decl_genesis_config_and_impl_default

0 commit comments

Comments
 (0)