aboutsummaryrefslogtreecommitdiff
path: root/src/javascript/jsc/api/bun.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/javascript/jsc/api/bun.zig')
-rw-r--r--src/javascript/jsc/api/bun.zig57
1 files changed, 56 insertions, 1 deletions
diff --git a/src/javascript/jsc/api/bun.zig b/src/javascript/jsc/api/bun.zig
index 8228139de..72d61d2e9 100644
--- a/src/javascript/jsc/api/bun.zig
+++ b/src/javascript/jsc/api/bun.zig
@@ -1623,8 +1623,49 @@ pub export fn Bun__escapeHTML(
const input_value = arguments[0];
const zig_str = input_value.getZigString(globalObject);
+ if (zig_str.len == 0)
+ return ZigString.Empty.toValue(globalObject);
+
if (zig_str.is16Bit()) {
- return input_value;
+ var input_slice = zig_str.utf16SliceAligned();
+ var escaped_html = strings.escapeHTMLForUTF16Input(globalObject.bunVM().allocator, input_slice) catch {
+ globalObject.vm().throwError(globalObject, ZigString.init("Out of memory").toValue(globalObject));
+ return JSC.JSValue.jsUndefined();
+ };
+
+ if (escaped_html.ptr == input_slice.ptr and escaped_html.len == input_slice.len) {
+ return input_value;
+ }
+
+ if (input_slice.len == 1) {
+ // single character escaped strings are statically allocated
+ return ZigString.init(std.mem.sliceAsBytes(escaped_html)).to16BitValue(globalObject);
+ }
+
+ if (comptime Environment.allow_assert) {
+ // assert that re-encoding the string produces the same result
+ std.debug.assert(
+ std.mem.eql(
+ u16,
+ (strings.toUTF16Alloc(bun.default_allocator, strings.toUTF8Alloc(bun.default_allocator, escaped_html) catch unreachable, false) catch unreachable).?,
+ escaped_html,
+ ),
+ );
+
+ // assert we do not allocate a new string unnecessarily
+ std.debug.assert(
+ !std.mem.eql(
+ u16,
+ input_slice,
+ escaped_html,
+ ),
+ );
+
+ // the output should always be longer than the input
+ std.debug.assert(escaped_html.len > input_slice.len);
+ }
+
+ return ZigString.from16(escaped_html.ptr, escaped_html.len).toExternalValue(globalObject);
} else {
var input_slice = zig_str.slice();
var escaped_html = strings.escapeHTMLForLatin1Input(globalObject.bunVM().allocator, input_slice) catch {
@@ -1641,6 +1682,20 @@ pub export fn Bun__escapeHTML(
return ZigString.init(escaped_html).toValue(globalObject);
}
+ if (comptime Environment.allow_assert) {
+ // the output should always be longer than the input
+ std.debug.assert(escaped_html.len > input_slice.len);
+
+ // assert we do not allocate a new string unnecessarily
+ std.debug.assert(
+ !std.mem.eql(
+ u8,
+ input_slice,
+ escaped_html,
+ ),
+ );
+ }
+
return ZigString.init(escaped_html).toExternalValue(globalObject);
}
}