Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: move ToUSVString() to node_util.cc #40204

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 2 additions & 5 deletions lib/internal/util.js
Expand Up @@ -28,10 +28,6 @@ const {
SymbolFor,
} = primordials;

const {
toUSVString: _toUSVString,
} = internalBinding('url');

const {
hideStackFrames,
codes: {
Expand All @@ -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');

Expand Down
58 changes: 0 additions & 58 deletions src/node_url.cc
Expand Up @@ -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:
Expand Down Expand Up @@ -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) { \
Expand Down Expand Up @@ -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)));
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
49 changes: 49 additions & 0 deletions src/node_util.cc
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/util-inl.h
Expand Up @@ -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>
Expand Down