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

Commit

Permalink
Use syn::Error to enforce whitelisted attributes on genesis config.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimpo committed Nov 7, 2019
1 parent 8749bb4 commit 39199bb
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

use srml_support_procedural_tools::syn_ext as ext;
use proc_macro2::TokenStream;
use syn::parse_quote;
use syn::{spanned::Spanned, parse_quote};
use quote::quote;
use super::super::{DeclStorageDefExt, StorageLineTypeDef};

Expand All @@ -43,8 +43,8 @@ pub struct GenesisConfigDef {
}

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

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

Self {
Ok(Self {
is_generic,
fields,
genesis_struct_decl,
genesis_struct,
genesis_impl,
genesis_where_clause,
}
})
}

fn get_genesis_config_field_defs(def: &DeclStorageDefExt) -> Vec<GenesisConfigFieldDef> {
fn get_genesis_config_field_defs(def: &DeclStorageDefExt)
-> syn::Result<Vec<GenesisConfigFieldDef>>
{
let mut config_field_defs = Vec::new();

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

for line in &def.extra_genesis_config_lines {
let attrs = line.attrs.iter()
.filter_map(|a| a.parse_meta().ok())
.filter(|m| m.path().is_ident("doc") || m.path().is_ident("serde"))
.collect();
.map(|attr| {
let meta = attr.parse_meta()?;
if meta.path().is_ident("doc") || meta.path().is_ident("serde") {
Ok(meta)
} else {
Err(syn::Error::new(
meta.span(),
"extra genesis config item only supports `doc` and `serde` attributes"
))
}
})
.collect::<syn::Result<_>>()?;

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

config_field_defs
Ok(config_field_defs)
}
}
9 changes: 6 additions & 3 deletions srml/support/procedural/src/storage/genesis_config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,13 @@ pub fn genesis_config_and_build_storage(
) -> TokenStream {
let builders = BuilderDef::from_def(scrate, def);
if !builders.blocks.is_empty() {
let genesis_config = &GenesisConfigDef::from_def(def);
let genesis_config = match GenesisConfigDef::from_def(def) {
Ok(genesis_config) => genesis_config,
Err(err) => return err.to_compile_error(),
};
let decl_genesis_config_and_impl_default =
decl_genesis_config_and_impl_default(scrate, genesis_config);
let impl_build_storage = impl_build_storage(scrate, def, genesis_config, &builders);
decl_genesis_config_and_impl_default(scrate, &genesis_config);
let impl_build_storage = impl_build_storage(scrate, def, &genesis_config, &builders);

quote!{
#decl_genesis_config_and_impl_default
Expand Down

0 comments on commit 39199bb

Please sign in to comment.