Skip to content

Commit

Permalink
src: do not ignore IDNA conversion error
Browse files Browse the repository at this point in the history
Old behavior can be restored using a special `lenient` mode, as used in
the legacy URL parser.

PR-URL: #11549
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
  • Loading branch information
TimothyGu authored and addaleax committed Mar 5, 2017
1 parent d329abf commit 1b6ba9e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 9 deletions.
5 changes: 4 additions & 1 deletion lib/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,10 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
// It only converts parts of the domain name that
// have non-ASCII characters, i.e. it doesn't matter if
// you call it with a domain that already is ASCII-only.
this.hostname = toASCII(this.hostname);

// Use lenient mode (`true`) to try to support even non-compliant
// URLs.
this.hostname = toASCII(this.hostname, true);
}

var p = this.port ? ':' + this.port : '';
Expand Down
20 changes: 14 additions & 6 deletions src/node_i18n.cc
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,8 @@ bool InitializeICUDirectory(const std::string& path) {

int32_t ToUnicode(MaybeStackBuffer<char>* buf,
const char* input,
size_t length) {
size_t length,
bool lenient) {
UErrorCode status = U_ZERO_ERROR;
uint32_t options = UIDNA_DEFAULT;
options |= UIDNA_NONTRANSITIONAL_TO_UNICODE;
Expand All @@ -435,7 +436,7 @@ int32_t ToUnicode(MaybeStackBuffer<char>* buf,
&status);
}

if (U_FAILURE(status)) {
if (U_FAILURE(status) || (!lenient && info.errors != 0)) {
len = -1;
buf->SetLength(0);
} else {
Expand All @@ -448,7 +449,8 @@ int32_t ToUnicode(MaybeStackBuffer<char>* buf,

int32_t ToASCII(MaybeStackBuffer<char>* buf,
const char* input,
size_t length) {
size_t length,
bool lenient) {
UErrorCode status = U_ZERO_ERROR;
uint32_t options = UIDNA_DEFAULT;
options |= UIDNA_NONTRANSITIONAL_TO_ASCII;
Expand All @@ -473,7 +475,7 @@ int32_t ToASCII(MaybeStackBuffer<char>* buf,
&status);
}

if (U_FAILURE(status)) {
if (U_FAILURE(status) || (!lenient && info.errors != 0)) {
len = -1;
buf->SetLength(0);
} else {
Expand All @@ -489,8 +491,11 @@ static void ToUnicode(const FunctionCallbackInfo<Value>& args) {
CHECK_GE(args.Length(), 1);
CHECK(args[0]->IsString());
Utf8Value val(env->isolate(), args[0]);
// optional arg
bool lenient = args[1]->BooleanValue(env->context()).FromJust();

MaybeStackBuffer<char> buf;
int32_t len = ToUnicode(&buf, *val, val.length());
int32_t len = ToUnicode(&buf, *val, val.length(), lenient);

if (len < 0) {
return env->ThrowError("Cannot convert name to Unicode");
Expand All @@ -508,8 +513,11 @@ static void ToASCII(const FunctionCallbackInfo<Value>& args) {
CHECK_GE(args.Length(), 1);
CHECK(args[0]->IsString());
Utf8Value val(env->isolate(), args[0]);
// optional arg
bool lenient = args[1]->BooleanValue(env->context()).FromJust();

MaybeStackBuffer<char> buf;
int32_t len = ToASCII(&buf, *val, val.length());
int32_t len = ToASCII(&buf, *val, val.length(), lenient);

if (len < 0) {
return env->ThrowError("Cannot convert name to ASCII");
Expand Down
6 changes: 4 additions & 2 deletions src/node_i18n.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ bool InitializeICUDirectory(const std::string& path);

int32_t ToASCII(MaybeStackBuffer<char>* buf,
const char* input,
size_t length);
size_t length,
bool lenient = false);
int32_t ToUnicode(MaybeStackBuffer<char>* buf,
const char* input,
size_t length);
size_t length,
bool lenient = false);

} // namespace i18n
} // namespace node
Expand Down

0 comments on commit 1b6ba9e

Please sign in to comment.