From e31fd7a9b958fe66dc5529d9f8daf775c9f3dc42 Mon Sep 17 00:00:00 2001 From: Darshan Sen Date: Sun, 23 May 2021 21:09:33 +0530 Subject: [PATCH] url: warn when operation requires ICU Continuation of: https://github.com/nodejs/node/pull/35099 Signed-off-by: Darshan Sen --- src/node_url.cc | 51 ++++++++++++++++++++++++++++++++----------------- src/node_url.h | 3 ++- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/node_url.cc b/src/node_url.cc index 554ee855848cc7..f04dc4787081a0 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -3,6 +3,7 @@ #include "node_errors.h" #include "node_external_reference.h" #include "node_i18n.h" +#include "node_process.h" // TODO: Replace with node_process-inl.h #include "util-inl.h" #include @@ -56,7 +57,8 @@ class URLHost { void ParseIPv4Host(const char* input, size_t length, bool* is_ipv4); void ParseIPv6Host(const char* input, size_t length); void ParseOpaqueHost(const char* input, size_t length); - void ParseHost(const char* input, + void ParseHost(Environment* env, + const char* input, size_t length, bool is_special, bool unicode = false); @@ -767,7 +769,9 @@ bool StartsWithWindowsDriveLetter(const char* p, const char* end) { } #if defined(NODE_HAVE_I18N_SUPPORT) -bool ToUnicode(const std::string& input, std::string* output) { +bool ToUnicode(Environment* env, + const std::string& input, + std::string* output) { MaybeStackBuffer buf; if (i18n::ToUnicode(&buf, input.c_str(), input.length()) < 0) return false; @@ -775,7 +779,9 @@ bool ToUnicode(const std::string& input, std::string* output) { return true; } -bool ToASCII(const std::string& input, std::string* output) { +bool ToASCII(Environment* env, + const std::string& input, + std::string* output) { MaybeStackBuffer buf; if (i18n::ToASCII(&buf, input.c_str(), input.length()) < 0) return false; @@ -786,12 +792,20 @@ bool ToASCII(const std::string& input, std::string* output) { } #else // Intentional non-ops if ICU is not present. -bool ToUnicode(const std::string& input, std::string* output) { +bool ToUnicode(Environment* env, + const std::string& input, + std::string* output) { + ProcessEmitWarning(env, + "Cannot convert to unicode when intl is disabled"); *output = input; return true; } -bool ToASCII(const std::string& input, std::string* output) { +bool ToASCII(Environment* env, + const std::string& input, + std::string* output) { + ProcessEmitWarning(env, + "Cannot convert to ASCII when intl is disabled"); *output = input; return true; } @@ -1022,7 +1036,8 @@ void URLHost::ParseOpaqueHost(const char* input, size_t length) { SetOpaque(std::move(output)); } -void URLHost::ParseHost(const char* input, +void URLHost::ParseHost(Environment* env, + const char* input, size_t length, bool is_special, bool unicode) { @@ -1045,7 +1060,7 @@ void URLHost::ParseHost(const char* input, std::string decoded = PercentDecode(input, length); // Then we have to punycode toASCII - if (!ToASCII(decoded, &decoded)) + if (!ToASCII(env, decoded, &decoded)) return; // If any of the following characters are still present, we have to fail @@ -1063,7 +1078,7 @@ void URLHost::ParseHost(const char* input, return; // If the unicode flag is set, run the result through punycode ToUnicode - if (unicode && !ToUnicode(decoded, &decoded)) + if (unicode && !ToUnicode(env, decoded, &decoded)) return; // It's not an IPv4 or IPv6 address, it must be a domain @@ -1169,7 +1184,8 @@ std::string URLHost::ToString() const { return dest; } -bool ParseHost(const std::string& input, +bool ParseHost(Environment* env, + const std::string& input, std::string* output, bool is_special, bool unicode = false) { @@ -1178,7 +1194,7 @@ bool ParseHost(const std::string& input, return true; } URLHost host; - host.ParseHost(input.c_str(), input.length(), is_special, unicode); + host.ParseHost(env, input.c_str(), input.length(), is_special, unicode); if (host.ParsingFailed()) return false; *output = host.ToStringMove(); @@ -1767,7 +1783,7 @@ void URL::Parse(const char* input, return; } url->flags |= URL_FLAGS_HAS_HOST; - if (!ParseHost(buffer, &url->host, special)) { + if (!ParseHost(env_, buffer, &url->host, special)) { url->flags |= URL_FLAGS_FAILED; return; } @@ -1794,7 +1810,7 @@ void URL::Parse(const char* input, return; } url->flags |= URL_FLAGS_HAS_HOST; - if (!ParseHost(buffer, &url->host, special)) { + if (!ParseHost(env_, buffer, &url->host, special)) { url->flags |= URL_FLAGS_FAILED; return; } @@ -1962,7 +1978,7 @@ void URL::Parse(const char* input, state = kPathStart; } else { std::string host; - if (!ParseHost(buffer, &host, special)) { + if (!ParseHost(env_, buffer, &host, special)) { url->flags |= URL_FLAGS_FAILED; return; } @@ -2298,7 +2314,7 @@ void DomainToASCII(const FunctionCallbackInfo& args) { URLHost host; // Assuming the host is used for a special scheme. - host.ParseHost(*value, value.length(), true); + host.ParseHost(env, *value, value.length(), true); if (host.ParsingFailed()) { args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING(env->isolate(), "")); return; @@ -2316,7 +2332,7 @@ void DomainToUnicode(const FunctionCallbackInfo& args) { URLHost host; // Assuming the host is used for a special scheme. - host.ParseHost(*value, value.length(), true, true); + host.ParseHost(env, *value, value.length(), true, true); if (host.ParsingFailed()) { args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING(env->isolate(), "")); return; @@ -2406,7 +2422,7 @@ std::string URL::ToFilePath() const { if ((context_.flags & URL_FLAGS_HAS_HOST) && context_.host.length() > 0) { std::string unicode_host; - if (!ToUnicode(context_.host, &unicode_host)) { + if (!ToUnicode(env_, context_.host, &unicode_host)) { return ""; } return "\\\\" + unicode_host + decoded_path; @@ -2442,7 +2458,8 @@ URL URL::FromFilePath(const std::string& file_path) { // This function works by calling out to a JS function that creates and // returns the JS URL object. Be mindful of the JS<->Native boundary // crossing that is required. -MaybeLocal URL::ToObject(Environment* env) const { +MaybeLocal URL::ToObject(Environment* env) { + env_ = env; Isolate* isolate = env->isolate(); Local context = env->context(); Context::Scope context_scope(context); diff --git a/src/node_url.h b/src/node_url.h index e42c2627179fcc..a3af2ba4847e17 100644 --- a/src/node_url.h +++ b/src/node_url.h @@ -173,7 +173,7 @@ class URL { // Get the file URL from native file system path. static URL FromFilePath(const std::string& file_path); - v8::MaybeLocal ToObject(Environment* env) const; + v8::MaybeLocal ToObject(Environment* env); URL(const URL&) = default; URL& operator=(const URL&) = default; @@ -183,6 +183,7 @@ class URL { URL() : URL("") {} private: + Environment* env_ = nullptr; struct url_data context_; };