Skip to content

Commit

Permalink
escape html attributes literals at build time
Browse files Browse the repository at this point in the history
  • Loading branch information
Pitasi committed Sep 9, 2023
1 parent aed4dc3 commit 459756e
Showing 1 changed file with 42 additions and 14 deletions.
56 changes: 42 additions & 14 deletions rscx-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use proc_macro2::{Literal, TokenTree};
use proc_macro2_diagnostics::Diagnostic;
use quote::{quote, quote_spanned, ToTokens};
use rstml::{
node::{Node, NodeAttribute, NodeElement, NodeName},
node::{KeyedAttribute, Node, NodeAttribute, NodeElement, NodeName},
Parser, ParserConfig,
};
use syn::{parse::Parse, spanned::Spanned, ItemStruct};
use syn::{parse::Parse, spanned::Spanned, Expr, ExprLit, ItemStruct};

#[proc_macro]
pub fn html(tokens: TokenStream) -> TokenStream {
Expand Down Expand Up @@ -160,18 +160,10 @@ fn walk_nodes<'a>(empty_elements: &HashSet<&str>, nodes: &'a Vec<Node>) -> WalkN
}});
}
NodeAttribute::Attribute(attribute) => {
let key = match attribute.key.to_string().as_str() {
"as_" => "as".to_string(),
_ => attribute.key.to_string(),
};
out.static_format.push_str(&format!(" {}", key));
if let Some(value) = attribute.value() {
out.static_format.push_str(r#"="{}""#);
out.values.push(quote! {
::rscx::html_escape::encode_unquoted_attribute(
&format!("{}", #value)
)
});
let (static_format, value) = walk_attribute(attribute);
out.static_format.push_str(&static_format);
if let Some(value) = value {
out.values.push(value);
}
}
}
Expand Down Expand Up @@ -240,6 +232,42 @@ fn walk_nodes<'a>(empty_elements: &HashSet<&str>, nodes: &'a Vec<Node>) -> WalkN
out
}

fn walk_attribute(attribute: &KeyedAttribute) -> (String, Option<proc_macro2::TokenStream>) {
let mut static_format = String::new();
let mut format_value = None;
let key = match attribute.key.to_string().as_str() {
"as_" => "as".to_string(),
_ => attribute.key.to_string(),
};
static_format.push_str(&format!(" {}", key));

match attribute.value() {
Some(Expr::Lit(ExprLit {
lit: syn::Lit::Str(value),
..
})) => {
static_format.push_str(&format!(
r#"="{}""#,
html_escape::encode_unquoted_attribute(&value.value())
));
}
Some(value) => {
static_format.push_str(r#"="{}""#);
format_value = Some(
quote! {
::rscx::html_escape::encode_double_quoted_attribute(
&format!("{}", #value)
)
}
.into_token_stream(),
);
}
None => {}
}

(static_format, format_value)
}

fn is_component_tag_name(name: &str) -> bool {
name.starts_with(|c: char| c.is_ascii_uppercase())
}
Expand Down

0 comments on commit 459756e

Please sign in to comment.