Compare commits

...

3 commits

Author SHA1 Message Date
lew
a33be3be6c fix: error text is escaped 2026-04-10 15:34:32 +01:00
lew
a1ddbba660 fix: alt-text on submitted drawings 2026-04-10 15:34:23 +01:00
lew
a06f380b67 fix: label-for on form elements 2026-04-10 15:33:57 +01:00

View file

@ -23,7 +23,7 @@ pub fn render_page(template: &str, config: &Config, entries: &[Entry], form_html
pub fn render_form(config: &Config) -> String { pub fn render_form(config: &Config) -> String {
let website_section = if config.enable_website_links { let website_section = if config.enable_website_links {
format!( format!(
"\n<label class=\"guestbook-label\">{}</label>\n<input class=\"guestbook-input\" name=\"website\">\n", "\n<label class=\"guestbook-label\" for=\"website\">{}</label>\n<input class=\"guestbook-input\" id=\"website\" name=\"website\">\n",
config.label_website config.label_website
) )
} else { } else {
@ -32,7 +32,7 @@ pub fn render_form(config: &Config) -> String {
let captcha_section = if config.enable_captcha { let captcha_section = if config.enable_captcha {
format!( format!(
"\n<label class=\"guestbook-label\">{}</label>\n<input class=\"guestbook-input\" name=\"captcha\" required>\n", "\n<label class=\"guestbook-label\" for=\"captcha\">{}</label>\n<input class=\"guestbook-input\" id=\"captcha\" name=\"captcha\" required>\n",
config.captcha_question config.captcha_question
) )
} else { } else {
@ -176,11 +176,11 @@ pub fn render_form(config: &Config) -> String {
format!( format!(
r#"<span class="guestbook-prompt">{prompt}</span> r#"<span class="guestbook-prompt">{prompt}</span>
<form class="guestbook-form" method="post" action="/submit" accept-charset="UTF-8"> <form class="guestbook-form" method="post" action="/submit" accept-charset="UTF-8">
<label class="guestbook-label">{label_name}</label> <label class="guestbook-label" for="name">{label_name}</label>
<input class="guestbook-input" name="name" required> <input class="guestbook-input" id="name" name="name" required>
{website_section} {website_section}
<label class="guestbook-label">{label_message}</label> <label class="guestbook-label" for="message">{label_message}</label>
<textarea class="guestbook-textarea" name="message" style="width:{tw}px;height:{th}px" required></textarea> <textarea class="guestbook-textarea" id="message" name="message" style="width:{tw}px;height:{th}px" required></textarea>
{captcha_section} {captcha_section}
{drawing_section}{voice_note_section}<input name="url" style="display:none" tabindex="-1" autocomplete="off"><button class="guestbook-button" type="submit">{button}</button> {drawing_section}{voice_note_section}<input name="url" style="display:none" tabindex="-1" autocomplete="off"><button class="guestbook-button" type="submit">{button}</button>
</form>"#, </form>"#,
@ -216,6 +216,7 @@ pub fn render_error_page(config: &Config, error: &str) -> String {
} else { } else {
&config.style &config.style
}; };
let error = escape_html(error);
format!( format!(
r#"<!DOCTYPE html> r#"<!DOCTYPE html>
<html lang="en"> <html lang="en">
@ -280,8 +281,9 @@ fn render_entry(entry: &Entry, config: &Config) -> String {
}; };
let drawing_html = if !entry.meta.drawing.is_empty() { let drawing_html = if !entry.meta.drawing.is_empty() {
format!( format!(
"<img class=\"entry-drawing\" src=\"/drawings/{}\">", "<img class=\"entry-drawing\" src=\"/drawings/{}\" alt=\"Drawing by {}\">",
escape_html(&entry.meta.drawing) escape_html(&entry.meta.drawing),
escape_html(&entry.meta.name)
) )
} else { } else {
String::new() String::new()
@ -545,7 +547,7 @@ mod tests {
entry.meta.drawing = "2026-04-09-abc123.png".into(); entry.meta.drawing = "2026-04-09-abc123.png".into();
let form = render_form(&config); let form = render_form(&config);
let html = render_page(DEFAULT_TEMPLATE, &config, &[entry], &form); let html = render_page(DEFAULT_TEMPLATE, &config, &[entry], &form);
assert!(html.contains(r#"<img class="entry-drawing" src="/drawings/2026-04-09-abc123.png">"#)); assert!(html.contains(r#"<img class="entry-drawing" src="/drawings/2026-04-09-abc123.png" alt="Drawing by alice">"#));
} }
#[test] #[test]
@ -557,7 +559,7 @@ mod tests {
let form = render_form(&config); let form = render_form(&config);
let html = render_page(DEFAULT_TEMPLATE, &config, &[entry], &form); let html = render_page(DEFAULT_TEMPLATE, &config, &[entry], &form);
// Drawing renders regardless // Drawing renders regardless
assert!(html.contains(r#"<img class="entry-drawing" src="/drawings/2026-04-09-abc123.png">"#)); assert!(html.contains(r#"<img class="entry-drawing" src="/drawings/2026-04-09-abc123.png" alt="Drawing by alice">"#));
// But body HTML is escaped // But body HTML is escaped
assert!(html.contains("&lt;script&gt;")); assert!(html.contains("&lt;script&gt;"));
} }