src: move ToUSVString() to node_util.cc

Since `toUSVString()` was exposed in `util` as a public API, not only
for internal `url` any more.

PR-URL: https://github.com/nodejs/node/pull/40204
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Zijian Liu <lxxyxzj@gmail.com>
This commit is contained in:
XadillaX 2021-09-24 13:59:45 +08:00
parent 281607d453
commit 0e561de643
4 changed files with 59 additions and 63 deletions

View File

@ -28,10 +28,6 @@ const {
SymbolFor,
} = primordials;
const {
toUSVString: _toUSVString,
} = internalBinding('url');
const {
hideStackFrames,
codes: {
@ -47,7 +43,8 @@ const {
setHiddenValue,
arrow_message_private_symbol: kArrowMessagePrivateSymbolIndex,
decorated_private_symbol: kDecoratedPrivateSymbolIndex,
sleep: _sleep
sleep: _sleep,
toUSVString: _toUSVString,
} = internalBinding('util');
const { isNativeError } = internalBinding('types');

View File

@ -52,9 +52,6 @@ namespace {
// https://url.spec.whatwg.org/#eof-code-point
constexpr char kEOL = -1;
// Used in ToUSVString().
constexpr char16_t kUnicodeReplacementCharacter = 0xFFFD;
// https://url.spec.whatwg.org/#concept-host
class URLHost {
public:
@ -160,14 +157,6 @@ enum url_error_cb_args {
#undef XX
};
#define CHAR_TEST(bits, name, expr) \
template <typename T> \
bool name(const T ch) { \
static_assert(sizeof(ch) >= (bits) / 8, \
"Character must be wider than " #bits " bits"); \
return (expr); \
}
#define TWO_CHAR_STRING_TEST(bits, name, expr) \
template <typename T> \
bool name(const T ch1, const T ch2) { \
@ -225,19 +214,8 @@ TWO_CHAR_STRING_TEST(8, IsWindowsDriveLetter,
TWO_CHAR_STRING_TEST(8, IsNormalizedWindowsDriveLetter,
(IsASCIIAlpha(ch1) && ch2 == ':'))
// If a UTF-16 character is a low/trailing surrogate.
CHAR_TEST(16, IsUnicodeTrail, (ch & 0xFC00) == 0xDC00)
// If a UTF-16 character is a surrogate.
CHAR_TEST(16, IsUnicodeSurrogate, (ch & 0xF800) == 0xD800)
// If a UTF-16 surrogate is a low/trailing one.
CHAR_TEST(16, IsUnicodeSurrogateTrail, (ch & 0x400) != 0)
#undef CHAR_TEST
#undef TWO_CHAR_STRING_TEST
bool BitAt(const uint8_t a[], const uint8_t i) {
return !!(a[i >> 3] & (1 << (i & 7)));
}
@ -1736,40 +1714,6 @@ void EncodeAuthSet(const FunctionCallbackInfo<Value>& args) {
String::NewFromUtf8(env->isolate(), output.c_str()).ToLocalChecked());
}
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,
NewStringType::kNormal,
value.length()).ToLocalChecked());
}
void DomainToASCII(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
CHECK_GE(args.Length(), 1);
@ -1820,7 +1764,6 @@ void Initialize(Local<Object> target,
Environment* env = Environment::GetCurrent(context);
env->SetMethod(target, "parse", Parse);
env->SetMethodNoSideEffect(target, "encodeAuth", EncodeAuthSet);
env->SetMethodNoSideEffect(target, "toUSVString", ToUSVString);
env->SetMethodNoSideEffect(target, "domainToASCII", DomainToASCII);
env->SetMethodNoSideEffect(target, "domainToUnicode", DomainToUnicode);
env->SetMethod(target, "setURLConstructor", SetURLConstructor);
@ -1838,7 +1781,6 @@ void Initialize(Local<Object> target,
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(Parse);
registry->Register(EncodeAuthSet);
registry->Register(ToUSVString);
registry->Register(DomainToASCII);
registry->Register(DomainToUnicode);
registry->Register(SetURLConstructor);

View File

@ -35,6 +35,18 @@ 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)
// If a UTF-16 character is a surrogate.
CHAR_TEST(16, IsUnicodeSurrogate, (ch & 0xF800) == 0xD800)
// If a UTF-16 surrogate is a low/trailing one.
CHAR_TEST(16, IsUnicodeSurrogateTrail, (ch & 0x400) != 0)
static void GetOwnNonIndexProperties(
const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
@ -282,6 +294,40 @@ static void IsConstructor(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(args[0].As<v8::Function>()->IsConstructor());
}
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(GetHiddenValue);
registry->Register(SetHiddenValue);
@ -299,6 +345,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(WeakReference::DecRef);
registry->Register(GuessHandleType);
registry->Register(IsConstructor);
registry->Register(ToUSVString);
}
void Initialize(Local<Object> target,
@ -370,6 +417,8 @@ void Initialize(Local<Object> target,
env->SetConstructorFunction(target, "WeakReference", weak_ref);
env->SetMethod(target, "guessHandleType", GuessHandleType);
env->SetMethodNoSideEffect(target, "toUSVString", ToUSVString);
}
} // namespace util

View File

@ -64,6 +64,14 @@
(((x) & 0x00000000000000FFull) << 56)
#endif
#define CHAR_TEST(bits, name, expr) \
template <typename T> \
bool name(const T ch) { \
static_assert(sizeof(ch) >= (bits) / 8, \
"Character must be wider than " #bits " bits"); \
return (expr); \
}
namespace node {
template <typename T>