1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
import { group } from "mitata";
import { bench, run } from "mitata";
var bunEscapeHTML_ = globalThis.escapeHTML || Bun.escapeHTML;
var bunEscapeHTML = function (str) {
if (str.length === 1) {
switch (str.charCodeAt(0)) {
case 34: // "
return """;
case 38: // &
return "&";
case 39: // '
return "'"; // modified from escape-html; used to be '''
case 60: // <
return "<";
case 62: // >
return ">";
default:
return str;
}
}
return bunEscapeHTML_(str);
};
const matchHtmlRegExp = /["'&<>]/;
/**
* Escapes special characters and HTML entities in a given html string.
*
* @param {string} string HTML string to escape for later insertion
* @return {string}
* @public
*/
const FIXTURE = require("fs")
.readFileSync(import.meta.dir + "/_fixture.txt", "utf8")
.split("")
.map((a) => {
if (a.charCodeAt(0) > 127) {
return "a";
}
return a;
})
.join("");
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>",
// "hello world",
// "hello world<script>alert('xss')</script>",
// "<",
// ">",
// `short value`,
`nothing to escape `.repeat(99999),
FIXTURE,
]) {
group(
{
summary: true,
name: `"` + input.substring(0, Math.min(input.length, 32)) + `"`,
},
() => {
bench(`react's escapeHTML`, () => reactEscapeHtml(input));
bench(`bun's escapeHTML`, () => bunEscapeHTML(input));
}
);
}
await run();
|