Skip to content

Commit

Permalink
encode attribute values
Browse files Browse the repository at this point in the history
  • Loading branch information
jcornaz committed Oct 31, 2024
1 parent 269629c commit 5942c09
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 9 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* Escape HTML strings
* `id` and `class` attributes
* Nodes
* Html document: `head` and `body`
* Text `h1`, `h2`, `h3`, `h4`, `h5`, `h6` and `text`
* Html document (`head` and `body`)
* Text (`h1`, `h2`, `h3`, `h4`, `h5`, `h6` and `text`)
* Container (`div`)
* `Node`, `Attribute` and `Document` types

[Unreleased]: https://github.com/jcornaz/fun-html/compare/...HEAD
6 changes: 5 additions & 1 deletion src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ use std::borrow::Cow;

use crate::Attribute;

pub fn attr(key: &'static str, value: impl Into<Cow<'static, str>>) -> Attribute {
Attribute::new(key, value)
}

pub fn id(id: impl Into<Cow<'static, str>>) -> Attribute {
Attribute::new("id", id)
attr("id", id)
}

pub fn class<'a>(classes: impl IntoIterator<Item = &'a str>) -> Attribute {
Expand Down
9 changes: 7 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ impl Display for Node {
write!(f, "<{tag}")?;
for attribute in attributes {
match &attribute.value {
AttributeValue::String(s) => write!(f, " {}=\"{s}\"", attribute.key)?,
AttributeValue::String(s) => write!(
f,
" {}=\"{}\"",
attribute.key,
html_escape::encode_double_quoted_attribute(s)
)?,
}
}
write!(f, ">")?;
Expand All @@ -94,7 +99,7 @@ impl Display for Node {
}
write!(f, "</{tag}>")?;
}
NodeInner::Text(text) => write!(f, "{}", html_escape::encode_safe(text))?,
NodeInner::Text(text) => write!(f, "{}", html_escape::encode_text(text))?,
}
Ok(())
}
Expand Down
7 changes: 7 additions & 0 deletions src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ use std::borrow::Cow;

use crate::{Attribute, Node, NodeInner};

pub fn div(
attributes: impl IntoIterator<Item = Attribute>,
children: impl IntoIterator<Item = Node>,
) -> Node {
Node::new("div", attributes, children)
}

pub fn head(
attributes: impl IntoIterator<Item = Attribute>,
children: impl IntoIterator<Item = Node>,
Expand Down
25 changes: 21 additions & 4 deletions tests/render_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,19 @@ fn should_render_empty_document() {

#[test]
fn should_render_attributes() {
let node = h1([class(["underlined", "blue"])], [text("Hello world!")]);
let string = format!("{node}");
assert_eq!(string, "<h1 class=\"underlined blue\">Hello world!</h1>")
let node = h1(
[class(["underlined", "blue"]), attr("foo", "bar")],
[text("Hello world!")],
);
assert_eq!(
node.to_string(),
"<h1 class=\"underlined blue\" foo=\"bar\">Hello world!</h1>"
)
}

#[rstest]
#[case(div([attr("foo", "bar")], [text("hello")]), "<div foo=\"bar\">hello</div>")]
#[case(div([attr("foo", "bar".to_string())], [text("hello".to_string())]), "<div foo=\"bar\">hello</div>")]
#[case(head([id("foo")], [text("hello")]), "<head id=\"foo\">hello</head>")]
#[case(body([id("foo")], [text("hello")]), "<body id=\"foo\">hello</body>")]
#[case(h1([id("foo")], [text("hello")]), "<h1 id=\"foo\">hello</h1>")]
Expand All @@ -36,8 +43,18 @@ fn should_render_node(#[case] def: Node, #[case] expected: &str) {
fn text_should_be_escaped() {
let input = "<script>alert('hello');</script>";
let string = text(input).to_string();
assert_eq!(string, "&lt;script&gt;alert('hello');&lt;/script&gt;");
}

#[rstest]
fn attribute_should_be_escaped() {
let string = div(
[attr("foo", "<script>\"\" { open: !close }")],
[text("hello")],
)
.to_string();
assert_eq!(
string,
"&lt;script&gt;alert(&#x27;hello&#x27;);&lt;&#x2F;script&gt;"
"<div foo=\"&lt;script&gt;&quot;&quot; { open: !close }\">hello</div>"
);
}

0 comments on commit 5942c09

Please sign in to comment.