Skip to content

Commit 8eb1135

Browse files
ronagtargos
authored andcommittedSep 4, 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 <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent abfd71b commit 8eb1135

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
@@ -2468,6 +2468,18 @@ const util = require('util');
24682468
util.log('Timestamped message.');
24692469
```
24702470

2471+
2472+
### `util.toUSVString(string)`
2473+
<!-- YAML
2474+
added: REPLACEME
2475+
-->
2476+
2477+
* `string` {string}
2478+
2479+
Returns the `string` after replacing any surrogate code points
2480+
(or equivalently, any unpaired surrogate code units) with the
2481+
Unicode "replacement character" U+FFFD.
2482+
24712483
[Common System Errors]: errors.md#errors_common_system_errors
24722484
[Custom inspection functions on objects]: #util_custom_inspection_functions_on_objects
24732485
[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
ERR_ARG_NOT_ITERABLE,
4650
ERR_INVALID_ARG_TYPE,
@@ -76,7 +80,6 @@ const {
7680
domainToASCII: _domainToASCII,
7781
domainToUnicode: _domainToUnicode,
7882
encodeAuth,
79-
toUSVString: _toUSVString,
8083
parse,
8184
setURLConstructor,
8285
URL_FLAGS_CANNOT_BE_BASE,
@@ -110,18 +113,6 @@ const IteratorPrototype = ObjectGetPrototypeOf(
110113
ObjectGetPrototypeOf([][SymbolIterator]())
111114
);
112115

113-
const unpairedSurrogateRe =
114-
/(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/;
115-
function toUSVString(val) {
116-
const str = `${val}`;
117-
// As of V8 5.5, `str.search()` (and `unpairedSurrogateRe[@@search]()`) are
118-
// slower than `unpairedSurrogateRe.exec()`.
119-
const match = RegExpPrototypeExec(unpairedSurrogateRe, str);
120-
if (!match)
121-
return str;
122-
return _toUSVString(str, match.index);
123-
}
124-
125116
// Refs: https://html.spec.whatwg.org/multipage/browsers.html#concept-origin-opaque
126117
const kOpaqueOrigin = 'null';
127118

‎lib/internal/util.js

+18
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@ const {
1414
ObjectSetPrototypeOf,
1515
Promise,
1616
ReflectConstruct,
17+
RegExpPrototypeExec,
1718
Set,
1819
Symbol,
1920
SymbolFor,
2021
} = primordials;
2122

23+
const {
24+
toUSVString: _toUSVString,
25+
} = internalBinding('url');
26+
2227
const {
2328
codes: {
2429
ERR_INVALID_ARG_TYPE,
@@ -44,6 +49,18 @@ const experimentalWarnings = new Set();
4449

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

52+
const unpairedSurrogateRe =
53+
/(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/;
54+
function toUSVString(val) {
55+
const str = `${val}`;
56+
// As of V8 5.5, `str.search()` (and `unpairedSurrogateRe[@@search]()`) are
57+
// slower than `unpairedSurrogateRe.exec()`.
58+
const match = RegExpPrototypeExec(unpairedSurrogateRe, str);
59+
if (!match)
60+
return str;
61+
return _toUSVString(str, match.index);
62+
}
63+
4764
let uvBinding;
4865

4966
function lazyUv() {
@@ -452,6 +469,7 @@ module.exports = {
452469
promisify,
453470
sleep,
454471
spliceOne,
472+
toUSVString,
455473
removeColors,
456474

457475
// Symbol used to customize promisify conversion

‎lib/util.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ const {
6060
deprecate,
6161
getSystemErrorMap,
6262
getSystemErrorName: internalErrorName,
63-
promisify
63+
promisify,
64+
toUSVString,
6465
} = require('internal/util');
6566

6667
let internalDeepEqual;
@@ -358,6 +359,7 @@ module.exports = {
358359
isPrimitive,
359360
log,
360361
promisify,
362+
toUSVString,
361363
TextDecoder,
362364
TextEncoder,
363365
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.