diff options
-rw-r--r-- | src/bun.js/api/html_rewriter.zig | 26 | ||||
-rw-r--r-- | src/deps/lol-html.zig | 11 | ||||
-rw-r--r-- | test/js/workerd/html-rewriter.test.js | 23 |
3 files changed, 37 insertions, 23 deletions
diff --git a/src/bun.js/api/html_rewriter.zig b/src/bun.js/api/html_rewriter.zig index 532e0ae1e..b309e07d7 100644 --- a/src/bun.js/api/html_rewriter.zig +++ b/src/bun.js/api/html_rewriter.zig @@ -1558,27 +1558,16 @@ pub const AttributeIterator = struct { return JSC.JSValue.jsNull(); }; - // TODO: don't clone here const value = attribute.value(); const name = attribute.name(); - defer name.deinit(); - defer value.deinit(); - var strs = [2]ZigString{ - ZigString.init(name.slice()), - ZigString.init(value.slice()), - }; - - var valid_strs: []ZigString = strs[0..2]; - - var array = JSC.JSValue.createStringArray( + return bun.String.toJSArray( globalObject, - valid_strs.ptr, - valid_strs.len, - true, + &[_]bun.String{ + name.toString(), + value.toString(), + }, ); - - return array; } }; pub const Element = struct { @@ -1864,8 +1853,9 @@ pub const Element = struct { pub fn getNamespaceURI(this: *Element, globalObject: *JSGlobalObject) JSValue { if (this.element == null) return JSValue.jsUndefined(); - - return ZigString.init(std.mem.span(this.element.?.namespaceURI())).toValueGC(globalObject); + var str = bun.String.create(std.mem.span(this.element.?.namespaceURI())); + defer str.deref(); + return str.toJS(globalObject); } pub fn getAttributes(this: *Element, globalObject: *JSGlobalObject) JSValue { diff --git a/src/deps/lol-html.zig b/src/deps/lol-html.zig index 50dab9592..bac422fb0 100644 --- a/src/deps/lol-html.zig +++ b/src/deps/lol-html.zig @@ -570,16 +570,17 @@ pub const HTMLString = extern struct { lol_html_str_free(.{ .ptr = @ptrCast([*]const u8, ptr), .len = len }); } - pub fn toJS(this: HTMLString, globalThis: *bun.JSC.JSGlobalObject) bun.JSC.JSValue { + pub fn toString(this: HTMLString) bun.String { const bytes = this.slice(); if (bun.strings.isAllASCII(bytes)) { - var external = bun.String.createExternal(bytes, true, @constCast(bytes.ptr), &deinit_external); - defer external.deref(); - return external.toJS(globalThis); + return bun.String.createExternal(bytes, true, @constCast(bytes.ptr), &deinit_external); } defer this.deinit(); + return bun.String.create(bytes); + } - var str = bun.String.create(bytes); + pub fn toJS(this: HTMLString, globalThis: *bun.JSC.JSGlobalObject) bun.JSC.JSValue { + var str = this.toString(); defer str.deref(); return str.toJS(globalThis); } diff --git a/test/js/workerd/html-rewriter.test.js b/test/js/workerd/html-rewriter.test.js index aaf912aff..44961df3b 100644 --- a/test/js/workerd/html-rewriter.test.js +++ b/test/js/workerd/html-rewriter.test.js @@ -365,3 +365,26 @@ it("get attribute - ascii", async () => { expect(el).toEqual("asciii"); } }); + +it("#3520", async () => { + const pairs = []; + + await new HTMLRewriter() + .on("p", { + element(element) { + for (const pair of element.attributes) { + pairs.push(pair); + } + }, + }) + .transform(new Response('<p šž="Õäöü" ab="Õäöü" šž="Õäöü" šž="dc" šž="🕵🏻"></p>')) + .text(); + + expect(pairs).toEqual([ + ["šž", "Õäöü"], + ["ab", "Õäöü"], + ["šž", "Õäöü"], + ["šž", "dc"], + ["šž", "🕵🏻"], + ]); +}); |