diff options
author | 2022-06-22 23:21:48 -0700 | |
---|---|---|
committer | 2022-06-22 23:21:48 -0700 | |
commit | 729d445b6885f69dd2c6355f38707bd42851c791 (patch) | |
tree | f87a7c408929ea3f57bbb7ace380cf869da83c0e /bench/escapeHTML.js | |
parent | 25f820c6bf1d8ec6d444ef579cc036b8c0607b75 (diff) | |
download | bun-729d445b6885f69dd2c6355f38707bd42851c791.tar.gz bun-729d445b6885f69dd2c6355f38707bd42851c791.tar.zst bun-729d445b6885f69dd2c6355f38707bd42851c791.zip |
change the directory structurejarred/rename
Diffstat (limited to 'bench/escapeHTML.js')
-rw-r--r-- | bench/escapeHTML.js | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/bench/escapeHTML.js b/bench/escapeHTML.js new file mode 100644 index 000000000..f186b1d2f --- /dev/null +++ b/bench/escapeHTML.js @@ -0,0 +1,122 @@ +import { group } from "mitata"; +import { bench, run } from "mitata"; +import { encode as htmlEntityEncode } from "html-entities"; +import { escape as heEscape } from "he"; + +var bunEscapeHTML = globalThis.escapeHTML || Bun.escapeHTML; + +const FIXTURE = require("fs") + .readFileSync(import.meta.dir + "/_fixture.txt", "utf8") + .split("") + .map((a) => { + if (a.charCodeAt(0) > 127) { + return "a"; + } + return a; + }) + .join(""); + +const FIXTURE_WITH_UNICODE = require("fs").readFileSync( + import.meta.dir + "/_fixture.txt", + "utf8" +); + +// from react-dom: +const matchHtmlRegExp = /["'&<>]/; + +function reactEscapeHtml(string) { + const str = "" + string; + const match = matchHtmlRegExp.exec(str); + + if (!match) { + return str; + } + + let escape; + let html = ""; + let index; + let lastIndex = 0; + + for (index = match.index; index < str.length; index++) { + switch (str.charCodeAt(index)) { + case 34: // " + escape = """; + break; + case 38: // & + escape = "&"; + break; + case 39: // ' + escape = "'"; // modified from escape-html; used to be ''' + break; + case 60: // < + escape = "<"; + break; + case 62: // > + escape = ">"; + break; + default: + continue; + } + + if (lastIndex !== index) { + html += str.substring(lastIndex, index); + } + + lastIndex = index + 1; + html += escape; + } + + return lastIndex !== index ? html + str.substring(lastIndex, index) : html; +} + +// for (let input of [ +// "<script>alert('xss')</script>", +// `long string, nothing to escape... `.repeat(9999), +// `long utf16 string, no esc 🤔🤔🤔🤔🤔` + "tex".repeat(4000), +// `smol`, +// // `medium string with <script>alert('xss')</script>`, + +// FIXTURE, +// // "[unicode]" + FIXTURE_WITH_UNICODE, +// ]) { +// group( +// { +// summary: true, +// name: +// `"` + +// input.substring(0, Math.min(input.length, 32)) + +// `"` + +// ` (${input.length} chars)`, +// }, +// () => { +// bench(`ReactDOM.escapeHTML`, () => reactEscapeHtml(input)); +// bench(`html-entities.encode`, () => htmlEntityEncode(input)); +// bench(`he.escape`, () => heEscape(input)); +// bench(`Bun.escapeHTML`, () => bunEscapeHTML(input)); +// } +// ); +// } + +for (let input of [ + `long string, nothing to escape... `.repeat(9999999 * 3), + FIXTURE.repeat(8000), + // "[unicode]" + FIXTURE_WITH_UNICODE, +]) { + group( + { + summary: true, + name: + `"` + + input.substring(0, Math.min(input.length, 32)) + + `"` + + ` (${new Intl.NumberFormat().format(input.length / 100_000_000_0)} GB)`, + }, + () => { + // bench(`ReactDOM.escapeHTML`, () => reactEscapeHtml(input)); + // bench(`html-entities.encode`, () => htmlEntityEncode(input)); + // bench(`he.escape`, () => heEscape(input)); + bench(`Bun.escapeHTML`, () => bunEscapeHTML(input)); + } + ); +} +await run(); |