lib,src: replace toUSVString with toWellFormed()

PR-URL: https://github.com/nodejs/node/pull/47342
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
Yagiz Nizipli 2023-11-29 11:00:57 -05:00 committed by GitHub
parent 2fa9503fee
commit 01dae5f877
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 31 additions and 128 deletions

View File

@ -1,27 +0,0 @@
'use strict';
const common = require('../common.js');
const inputs = {
valid: 'adsfadsfadsf',
validsurr: '\uda23\ude23\uda1f\udfaa\ud800\udfff\uda23\ude23\uda1f\udfaa' +
'\ud800\udfff',
someinvalid: 'asasfdfasd\uda23',
allinvalid: '\udc45\uda23 \udf00\udc00 \udfaa\uda12 \udc00\udfaa',
nonstring: { toString() { return 'asdf'; } },
};
const bench = common.createBenchmark(main, {
input: Object.keys(inputs),
n: [5e7],
}, {
flags: ['--expose-internals'],
});
function main({ input, n }) {
const { toUSVString } = require('internal/url');
const str = inputs[input];
bench.start();
for (let i = 0; i < n; i++)
toUSVString(str);
bench.end(n);
}

View File

@ -1,21 +0,0 @@
'use strict';
const common = require('../common');
const BASE = 'string\ud801';
const bench = common.createBenchmark(main, {
n: [1e5],
size: [10, 100, 500],
});
function main({ n, size }) {
const { toUSVString } = require('util');
const str = BASE.repeat(size);
bench.start();
for (let i = 0; i < n; i++) {
toUSVString(str);
}
bench.end(n);
}

View File

@ -4,6 +4,7 @@ const {
DateNow,
NumberIsNaN,
ObjectDefineProperties,
StringPrototypeToWellFormed,
SymbolToStringTag,
} = primordials;
@ -15,7 +16,6 @@ const {
customInspectSymbol: kInspect,
kEnumerableProperty,
kEmptyObject,
toUSVString,
} = require('internal/util');
const {
@ -55,7 +55,7 @@ class File extends Blob {
lastModified = DateNow();
}
this.#name = toUSVString(fileName);
this.#name = StringPrototypeToWellFormed(`${fileName}`);
this.#lastModified = lastModified;
}

View File

@ -26,6 +26,7 @@ const {
StringPrototypeIndexOf,
StringPrototypeSlice,
StringPrototypeStartsWith,
StringPrototypeToWellFormed,
Symbol,
SymbolIterator,
SymbolToStringTag,
@ -42,7 +43,6 @@ const {
const {
getConstructorOf,
removeColors,
toUSVString,
kEnumerableProperty,
SideEffectFreeRegExpPrototypeSymbolReplace,
} = require('internal/util');
@ -366,7 +366,11 @@ class URLSearchParams {
throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]');
}
// Append (innerSequence[0], innerSequence[1]) to querys list.
ArrayPrototypePush(this.#searchParams, toUSVString(pair[0]), toUSVString(pair[1]));
ArrayPrototypePush(
this.#searchParams,
StringPrototypeToWellFormed(`${pair[0]}`),
StringPrototypeToWellFormed(`${pair[1]}`),
);
} else {
if (((typeof pair !== 'object' && typeof pair !== 'function') ||
typeof pair[SymbolIterator] !== 'function')) {
@ -377,7 +381,7 @@ class URLSearchParams {
for (const element of pair) {
length++;
ArrayPrototypePush(this.#searchParams, toUSVString(element));
ArrayPrototypePush(this.#searchParams, StringPrototypeToWellFormed(`${element}`));
}
// If innerSequence's size is not 2, then throw a TypeError.
@ -395,8 +399,8 @@ class URLSearchParams {
const key = keys[i];
const desc = ReflectGetOwnPropertyDescriptor(init, key);
if (desc !== undefined && desc.enumerable) {
const typedKey = toUSVString(key);
const typedValue = toUSVString(init[key]);
const typedKey = StringPrototypeToWellFormed(key);
const typedValue = StringPrototypeToWellFormed(`${init[key]}`);
// Two different keys may become the same USVString after normalization.
// In that case, we retain the later one. Refer to WPT.
@ -413,7 +417,7 @@ class URLSearchParams {
}
} else {
// https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams
init = toUSVString(init);
init = StringPrototypeToWellFormed(`${init}`);
this.#searchParams = init ? parseParams(init) : [];
}
}
@ -468,8 +472,8 @@ class URLSearchParams {
throw new ERR_MISSING_ARGS('name', 'value');
}
name = toUSVString(name);
value = toUSVString(value);
name = StringPrototypeToWellFormed(`${name}`);
value = StringPrototypeToWellFormed(`${value}`);
ArrayPrototypePush(this.#searchParams, name, value);
if (this.#context) {
this.#context.search = this.toString();
@ -485,10 +489,10 @@ class URLSearchParams {
}
const list = this.#searchParams;
name = toUSVString(name);
name = StringPrototypeToWellFormed(`${name}`);
if (value !== undefined) {
value = toUSVString(value);
value = StringPrototypeToWellFormed(`${value}`);
for (let i = 0; i < list.length;) {
if (list[i] === name && list[i + 1] === value) {
list.splice(i, 2);
@ -519,7 +523,7 @@ class URLSearchParams {
}
const list = this.#searchParams;
name = toUSVString(name);
name = StringPrototypeToWellFormed(`${name}`);
for (let i = 0; i < list.length; i += 2) {
if (list[i] === name) {
return list[i + 1];
@ -538,7 +542,7 @@ class URLSearchParams {
const list = this.#searchParams;
const values = [];
name = toUSVString(name);
name = StringPrototypeToWellFormed(`${name}`);
for (let i = 0; i < list.length; i += 2) {
if (list[i] === name) {
values.push(list[i + 1]);
@ -556,10 +560,10 @@ class URLSearchParams {
}
const list = this.#searchParams;
name = toUSVString(name);
name = StringPrototypeToWellFormed(`${name}`);
if (value !== undefined) {
value = toUSVString(value);
value = StringPrototypeToWellFormed(`${value}`);
}
for (let i = 0; i < list.length; i += 2) {
@ -582,8 +586,8 @@ class URLSearchParams {
}
const list = this.#searchParams;
name = toUSVString(name);
value = toUSVString(value);
name = StringPrototypeToWellFormed(`${name}`);
value = StringPrototypeToWellFormed(`${value}`);
// If there are any name-value pairs whose name is `name`, in `list`, set
// the value of the first such name-value pair to `value` and remove the
@ -773,7 +777,7 @@ class URL {
throw new ERR_MISSING_ARGS('url');
}
// toUSVString is not needed.
// StringPrototypeToWellFormed is not needed.
input = `${input}`;
if (base !== undefined) {
@ -1006,7 +1010,7 @@ class URL {
}
set search(value) {
const href = bindingUrl.update(this.#context.href, updateActions.kSearch, toUSVString(value));
const href = bindingUrl.update(this.#context.href, updateActions.kSearch, StringPrototypeToWellFormed(`${value}`));
if (href) {
this.#updateContext(href);
}
@ -1297,7 +1301,7 @@ function domainToASCII(domain) {
if (arguments.length < 1)
throw new ERR_MISSING_ARGS('domain');
// toUSVString is not needed.
// StringPrototypeToWellFormed is not needed.
return bindingUrl.domainToASCII(`${domain}`);
}
@ -1305,7 +1309,7 @@ function domainToUnicode(domain) {
if (arguments.length < 1)
throw new ERR_MISSING_ARGS('domain');
// toUSVString is not needed.
// StringPrototypeToWellFormed is not needed.
return bindingUrl.domainToUnicode(`${domain}`);
}
@ -1501,7 +1505,6 @@ function getURLOrigin(url) {
}
module.exports = {
toUSVString,
fileURLToPath,
pathToFileURL,
toPathIfFileURL,

View File

@ -62,7 +62,6 @@ const {
decorated_private_symbol,
},
sleep: _sleep,
toUSVString: _toUSVString,
} = internalBinding('util');
const { isNativeError, isPromise } = internalBinding('types');
const { getOptionValue } = require('internal/options');
@ -73,18 +72,6 @@ const experimentalWarnings = new SafeSet();
const colorRegExp = /\u001b\[\d\d?m/g; // eslint-disable-line no-control-regex
const unpairedSurrogateRe =
/(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/;
function toUSVString(val) {
const str = `${val}`;
// As of V8 5.5, `str.search()` (and `unpairedSurrogateRe[@@search]()`) are
// slower than `unpairedSurrogateRe.exec()`.
const match = RegExpPrototypeExec(unpairedSurrogateRe, str);
if (!match)
return str;
return _toUSVString(str, match.index);
}
let uvBinding;
function lazyUv() {
@ -913,7 +900,6 @@ module.exports = {
sleep,
spliceOne,
setupCoverageHooks,
toUSVString,
removeColors,
// Symbol used to customize promisify conversion

View File

@ -44,6 +44,7 @@ const {
ObjectValues,
ReflectApply,
StringPrototypePadStart,
StringPrototypeToWellFormed,
} = primordials;
const {
@ -75,7 +76,6 @@ const {
getSystemErrorMap,
getSystemErrorName: internalErrorName,
promisify,
toUSVString,
defineLazyProperties,
} = require('internal/util');
@ -452,7 +452,9 @@ module.exports = {
'DEP0059'),
promisify,
stripVTControlCharacters,
toUSVString,
toUSVString(input) {
return StringPrototypeToWellFormed(`${input}`);
},
get transferableAbortSignal() {
return lazyAbortController().transferableAbortSignal;
},

View File

@ -37,9 +37,6 @@ using v8::String;
using v8::Uint32;
using v8::Value;
// Used in ToUSVString().
constexpr char16_t kUnicodeReplacementCharacter = 0xFFFD;
// If a UTF-16 character is a low/trailing surrogate.
CHAR_TEST(16, IsUnicodeTrail, (ch & 0xFC00) == 0xDC00)
@ -240,40 +237,6 @@ static uint32_t FastGuessHandleType(Local<Value> receiver, const uint32_t fd) {
CFunction fast_guess_handle_type_(CFunction::Make(FastGuessHandleType));
static void ToUSVString(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
CHECK_GE(args.Length(), 2);
CHECK(args[0]->IsString());
CHECK(args[1]->IsNumber());
TwoByteValue value(env->isolate(), args[0]);
int64_t start = args[1]->IntegerValue(env->context()).FromJust();
CHECK_GE(start, 0);
for (size_t i = start; i < value.length(); i++) {
char16_t c = value[i];
if (!IsUnicodeSurrogate(c)) {
continue;
} else if (IsUnicodeSurrogateTrail(c) || i == value.length() - 1) {
value[i] = kUnicodeReplacementCharacter;
} else {
char16_t d = value[i + 1];
if (IsUnicodeTrail(d)) {
i++;
} else {
value[i] = kUnicodeReplacementCharacter;
}
}
}
args.GetReturnValue().Set(
String::NewFromTwoByte(env->isolate(),
*value,
v8::NewStringType::kNormal,
value.length()).ToLocalChecked());
}
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(GetPromiseDetails);
registry->Register(GetProxyDetails);
@ -288,7 +251,6 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(GuessHandleType);
registry->Register(FastGuessHandleType);
registry->Register(fast_guess_handle_type_.GetTypeInfo());
registry->Register(ToUSVString);
}
void Initialize(Local<Object> target,
@ -403,8 +365,6 @@ void Initialize(Local<Object> target,
"guessHandleType",
GuessHandleType,
&fast_guess_handle_type_);
SetMethodNoSideEffect(context, target, "toUSVString", ToUSVString);
}
} // namespace util

View File

@ -43,5 +43,4 @@ export interface UtilBinding {
shouldAbortOnUncaughtToggle: [shouldAbort: 0 | 1];
WeakReference: typeof InternalUtilBinding.WeakReference;
guessHandleType(fd: number): 'TCP' | 'TTY' | 'UDP' | 'FILE' | 'PIPE' | 'UNKNOWN';
toUSVString(str: string, start: number): string;
}

View File

@ -420,6 +420,7 @@ declare namespace primordials {
export const StringPrototypeToLocaleUpperCase: UncurryThis<typeof String.prototype.toLocaleUpperCase>
export const StringPrototypeToLowerCase: UncurryThis<typeof String.prototype.toLowerCase>
export const StringPrototypeToUpperCase: UncurryThis<typeof String.prototype.toUpperCase>
export const StringPrototypeToWellFormed: UncurryThis<typeof String.prototype.toWellFormed>
export const StringPrototypeValueOf: UncurryThis<typeof String.prototype.valueOf>
export const StringPrototypeReplaceAll: UncurryThis<typeof String.prototype.replaceAll>
export import Symbol = globalThis.Symbol;