Skip to content

Commit

Permalink
Escape special html characters in attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
AljoschaMeyer committed Jan 16, 2024
1 parent 30ee7a2 commit 696716b
Showing 1 changed file with 31 additions and 2 deletions.
33 changes: 31 additions & 2 deletions h.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@ import { Expression, Macro, Invocation, new_macro, is_expression } from "./tsgen

export type Attributes = Record<PropertyKey, Expression>;

function escape_html(raw: string): string {
return raw.replaceAll(/&|<|>|"|'/g, match => {
if (match === `&`) {
return `&amp;`;
} else if (match === `<`) {
return `&lt;`;
} else
if (match === `>`) {
return `&gt;`;
} else
if (match === `"`) {
return `&quot;`;
} else
if (match === `'`) {
return `&#39;`;
} else {
throw new Error("unreachable");
}
});
}

export function html_escape(exp: Expression): Expression {
const macro = new_macro(
undefined,
(expanded, _ctx) => escape_html(expanded),
);
return new Invocation(macro, [exp]);
}

function mac(tag_name: string, attributes: Attributes): Macro {
return new_macro(
(args, _state) => {
Expand Down Expand Up @@ -30,7 +59,7 @@ function render_attributes(attributes: Attributes): Expression {
const fragments: Expression[][] = [];

for (const name in attributes) {
const value = attributes[name];
const value = html_escape(attributes[name]);
if (value === "") {
fragments.push([name]);
} else {
Expand Down Expand Up @@ -79,7 +108,7 @@ export function img(src: Expression, alt: Expression, attributes: Attributes = {
const macro = new_macro(
(args, _ctx) => {
return [
`<img src="`, args[0], `" alt="`, args[1], `"`, render_attributes(attributes), ">",
`<img src="`, html_escape(args[0]), `" alt="`, html_escape(args[1]), `"`, render_attributes(attributes), ">",
];
},
);
Expand Down

0 comments on commit 696716b

Please sign in to comment.