Skip to content

Commit

Permalink
fix(ext): use String#toWellFormed in ext/webidl and ext/node (#21054)
Browse files Browse the repository at this point in the history
Fixes #18802 

This PR adds `util.toUSVString` to node:util:

```js
import util from "node:util";
util.toUSVString("string\ud801"); // => "string\ufffd"
```
  • Loading branch information
petamoriken authored Nov 6, 2023
1 parent 7eb34c7 commit 90189dd
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 26 deletions.
3 changes: 1 addition & 2 deletions cli/tests/node_compat/test/parallel/test-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,7 @@ assert.strictEqual(util.isFunction(function() {}), true);
assert.strictEqual(util.isFunction(), false);
assert.strictEqual(util.isFunction('string'), false);

// TODO(wafuwafu13): Enable this when `toUSVString` is ready.
// assert.strictEqual(util.toUSVString('string\ud801'), 'string\ufffd');
assert.strictEqual(util.toUSVString('string\ud801'), 'string\ufffd');

{
assert.strictEqual(util.types.isNativeError(new Error()), true);
Expand Down
8 changes: 8 additions & 0 deletions cli/tests/unit_node/util_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ Deno.test({
},
});

Deno.test({
name: "[util] toUSVString",
fn() {
assertEquals(util.toUSVString("foo"), "foo");
assertEquals(util.toUSVString("bar\ud801"), "bar\ufffd");
},
});

Deno.test({
name: "[util] isDate",
fn() {
Expand Down
10 changes: 10 additions & 0 deletions ext/node/polyfills/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ const {
SafeSet,
SetPrototypeAdd,
SetPrototypeHas,
StringPrototypeIsWellFormed,
StringPrototypePadStart,
StringPrototypeToWellFormed,
} = primordials;

export {
Expand Down Expand Up @@ -187,6 +189,13 @@ export const TextDecoder = _TextDecoder;
export type TextEncoder = import("./_utils.ts")._TextEncoder;
export const TextEncoder = _TextEncoder;

export function toUSVString(str: string): string {
if (StringPrototypeIsWellFormed(str)) {
return str;
}
return StringPrototypeToWellFormed(str);
}

function pad(n: number) {
return StringPrototypePadStart(NumberPrototypeToString(n), 2, "0");
}
Expand Down Expand Up @@ -309,6 +318,7 @@ export default {
stripVTControlCharacters,
TextDecoder,
TextEncoder,
toUSVString,
log,
debuglog,
isDeepStrictEqual,
Expand Down
26 changes: 2 additions & 24 deletions ext/webidl/00_webidl.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ const {
// TODO(lucacasonato): add SharedArrayBuffer to primordials
// SharedArrayBufferPrototype
String,
StringFromCodePoint,
StringPrototypeCharCodeAt,
StringPrototypeToWellFormed,
Symbol,
SymbolIterator,
SymbolToStringTag,
Expand Down Expand Up @@ -425,29 +425,7 @@ converters.ByteString = (V, prefix, context, opts) => {

converters.USVString = (V, prefix, context, opts) => {
const S = converters.DOMString(V, prefix, context, opts);
const n = S.length;
let U = "";
for (let i = 0; i < n; ++i) {
const c = StringPrototypeCharCodeAt(S, i);
if (c < 0xd800 || c > 0xdfff) {
U += StringFromCodePoint(c);
} else if (0xdc00 <= c && c <= 0xdfff) {
U += StringFromCodePoint(0xfffd);
} else if (i === n - 1) {
U += StringFromCodePoint(0xfffd);
} else {
const d = StringPrototypeCharCodeAt(S, i + 1);
if (0xdc00 <= d && d <= 0xdfff) {
const a = c & 0x3ff;
const b = d & 0x3ff;
U += StringFromCodePoint((2 << 15) + (2 << 9) * a + b);
++i;
} else {
U += StringFromCodePoint(0xfffd);
}
}
}
return U;
return StringPrototypeToWellFormed(S);
};

converters.object = (V, prefix, context, _opts) => {
Expand Down

0 comments on commit 90189dd

Please sign in to comment.