Escape single quotes on the buyer-facing buy page
buy_page.rs kept a private html_escape that omitted the `'` escape the canonical api::mod.rs impl has, so operator/product/discount-code text rendered into HTML attributes was under-escaped. Drop the fork, reuse the canonical escaper, and add a unit test covering the single quote.
This commit is contained in:
@@ -16,6 +16,9 @@
|
||||
//! buyer-facing surface — easy to deploy, no asset hosting required.
|
||||
|
||||
use crate::api::AppState;
|
||||
// Reuse the canonical HTML escaper (escapes `'` as well as `&<>"`) instead of a
|
||||
// private copy, so the buyer-facing page can't fall behind on attribute escaping.
|
||||
use crate::api::html_escape;
|
||||
use crate::db::repo;
|
||||
use axum::{
|
||||
extract::{Path, Query, State},
|
||||
@@ -1533,13 +1536,6 @@ code{{background:#eee;padding:0.1em 0.4em;border-radius:4px;font-family:ui-monos
|
||||
)
|
||||
}
|
||||
|
||||
fn html_escape(s: &str) -> String {
|
||||
s.replace('&', "&")
|
||||
.replace('<', "<")
|
||||
.replace('>', ">")
|
||||
.replace('"', """)
|
||||
}
|
||||
|
||||
fn format_thousands(n: i64) -> String {
|
||||
// Renders 50000 as "50,000" — visible price legibility for sat amounts.
|
||||
let s = n.to_string();
|
||||
|
||||
@@ -1193,3 +1193,22 @@ async fn pubkey(
|
||||
"public_key_pem": state.keypair.public_key_pem,
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// The canonical escaper must cover the single quote — operator/product/
|
||||
/// discount-code text renders into HTML attributes (incl. single-quoted),
|
||||
/// so omitting `'` is an injection hole. Guards against re-forking a copy
|
||||
/// that drops it (the bug that lived in `buy_page.rs`).
|
||||
#[test]
|
||||
fn html_escape_covers_single_quote_and_friends() {
|
||||
assert_eq!(html_escape("'"), "'");
|
||||
assert_eq!(
|
||||
html_escape(r#"<a href='x' title="y">&</a>"#),
|
||||
"<a href='x' title="y">&</a>"
|
||||
);
|
||||
assert_eq!(html_escape("plain"), "plain");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user