Skip to content

Commit 6640037

Browse files
ronagtargos
authored andcommittedAug 22, 2021
util: expose toUSVString
Expose toUSVString so it can be used by user libraries. PR-URL: #39814 Refs: nodejs/undici#986 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
1 parent 79079ea commit 6640037

File tree

5 files changed

+41
-16
lines changed

5 files changed

+41
-16
lines changed
 

‎doc/api/util.md

+12
Original file line numberDiff line numberDiff line change
@@ -2490,6 +2490,18 @@ const util = require('util');
24902490
util.log('Timestamped message.');
24912491
```
24922492

2493+
2494+
### `util.toUSVString(string)`
2495+
<!-- YAML
2496+
added: REPLACEME
2497+
-->
2498+
2499+
* `string` {string}
2500+
2501+
Returns the `string` after replacing any surrogate code points
2502+
(or equivalently, any unpaired surrogate code units) with the
2503+
Unicode "replacement character" U+FFFD.
2504+
24932505
[Common System Errors]: errors.md#errors_common_system_errors
24942506
[Custom inspection functions on objects]: #util_custom_inspection_functions_on_objects
24952507
[Custom promisified functions]: #util_custom_promisified_functions

‎lib/internal/url.js

+6-15
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const {
1919
ReflectApply,
2020
ReflectGetOwnPropertyDescriptor,
2121
ReflectOwnKeys,
22-
RegExpPrototypeExec,
2322
String,
2423
StringPrototypeCharCodeAt,
2524
StringPrototypeIncludes,
@@ -40,7 +39,12 @@ const {
4039
isHexTable
4140
} = require('internal/querystring');
4241

43-
const { getConstructorOf, removeColors } = require('internal/util');
42+
const {
43+
getConstructorOf,
44+
removeColors,
45+
toUSVString,
46+
} = require('internal/util');
47+
4448
const {
4549
codes: {
4650
ERR_ARG_NOT_ITERABLE,
@@ -82,7 +86,6 @@ const {
8286
domainToASCII: _domainToASCII,
8387
domainToUnicode: _domainToUnicode,
8488
encodeAuth,
85-
toUSVString: _toUSVString,
8689
parse,
8790
setURLConstructor,
8891
URL_FLAGS_CANNOT_BE_BASE,
@@ -139,18 +142,6 @@ const IteratorPrototype = ObjectGetPrototypeOf(
139142
ObjectGetPrototypeOf([][SymbolIterator]())
140143
);
141144

142-
const unpairedSurrogateRe =
143-
/(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/;
144-
function toUSVString(val) {
145-
const str = `${val}`;
146-
// As of V8 5.5, `str.search()` (and `unpairedSurrogateRe[@@search]()`) are
147-
// slower than `unpairedSurrogateRe.exec()`.
148-
const match = RegExpPrototypeExec(unpairedSurrogateRe, str);
149-
if (!match)
150-
return str;
151-
return _toUSVString(str, match.index);
152-
}
153-
154145
// Refs: https://html.spec.whatwg.org/multipage/browsers.html#concept-origin-opaque
155146
const kOpaqueOrigin = 'null';
156147

‎lib/internal/util.js

+18
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const {
1717
Promise,
1818
ReflectApply,
1919
ReflectConstruct,
20+
RegExpPrototypeExec,
2021
RegExpPrototypeTest,
2122
SafeMap,
2223
SafeSet,
@@ -27,6 +28,10 @@ const {
2728
SymbolFor,
2829
} = primordials;
2930

31+
const {
32+
toUSVString: _toUSVString,
33+
} = internalBinding('url');
34+
3035
const {
3136
hideStackFrames,
3237
codes: {
@@ -52,6 +57,18 @@ const experimentalWarnings = new SafeSet();
5257

5358
const colorRegExp = /\u001b\[\d\d?m/g; // eslint-disable-line no-control-regex
5459

60+
const unpairedSurrogateRe =
61+
/(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/;
62+
function toUSVString(val) {
63+
const str = `${val}`;
64+
// As of V8 5.5, `str.search()` (and `unpairedSurrogateRe[@@search]()`) are
65+
// slower than `unpairedSurrogateRe.exec()`.
66+
const match = RegExpPrototypeExec(unpairedSurrogateRe, str);
67+
if (!match)
68+
return str;
69+
return _toUSVString(str, match.index);
70+
}
71+
5572
let uvBinding;
5673

5774
function lazyUv() {
@@ -497,6 +514,7 @@ module.exports = {
497514
sleep,
498515
spliceOne,
499516
structuredClone,
517+
toUSVString,
500518
removeColors,
501519

502520
// Symbol used to customize promisify conversion

‎lib/util.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ const {
7272
deprecate,
7373
getSystemErrorMap,
7474
getSystemErrorName: internalErrorName,
75-
promisify
75+
promisify,
76+
toUSVString,
7677
} = require('internal/util');
7778

7879
let internalDeepEqual;
@@ -368,6 +369,7 @@ module.exports = {
368369
isPrimitive,
369370
log,
370371
promisify,
372+
toUSVString,
371373
TextDecoder,
372374
TextEncoder,
373375
types

‎test/parallel/test-util.js

+2
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ assert.strictEqual(util.isFunction(function() {}), true);
148148
assert.strictEqual(util.isFunction(), false);
149149
assert.strictEqual(util.isFunction('string'), false);
150150

151+
assert.strictEqual(util.toUSVString('string\ud801'), 'string\ufffd');
152+
151153
{
152154
assert.strictEqual(util.types.isNativeError(new Error()), true);
153155
assert.strictEqual(util.types.isNativeError(new TypeError()), true);

0 commit comments

Comments
 (0)
Please sign in to comment.