Skip to content

Commit 1b6ba9e

Browse files
TimothyGuaddaleax
authored andcommitted
src: do not ignore IDNA conversion error
Old behavior can be restored using a special `lenient` mode, as used in the legacy URL parser. PR-URL: #11549 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
1 parent d329abf commit 1b6ba9e

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

lib/url.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,10 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
319319
// It only converts parts of the domain name that
320320
// have non-ASCII characters, i.e. it doesn't matter if
321321
// you call it with a domain that already is ASCII-only.
322-
this.hostname = toASCII(this.hostname);
322+
323+
// Use lenient mode (`true`) to try to support even non-compliant
324+
// URLs.
325+
this.hostname = toASCII(this.hostname, true);
323326
}
324327

325328
var p = this.port ? ':' + this.port : '';

src/node_i18n.cc

+14-6
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,8 @@ bool InitializeICUDirectory(const std::string& path) {
410410

411411
int32_t ToUnicode(MaybeStackBuffer<char>* buf,
412412
const char* input,
413-
size_t length) {
413+
size_t length,
414+
bool lenient) {
414415
UErrorCode status = U_ZERO_ERROR;
415416
uint32_t options = UIDNA_DEFAULT;
416417
options |= UIDNA_NONTRANSITIONAL_TO_UNICODE;
@@ -435,7 +436,7 @@ int32_t ToUnicode(MaybeStackBuffer<char>* buf,
435436
&status);
436437
}
437438

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

449450
int32_t ToASCII(MaybeStackBuffer<char>* buf,
450451
const char* input,
451-
size_t length) {
452+
size_t length,
453+
bool lenient) {
452454
UErrorCode status = U_ZERO_ERROR;
453455
uint32_t options = UIDNA_DEFAULT;
454456
options |= UIDNA_NONTRANSITIONAL_TO_ASCII;
@@ -473,7 +475,7 @@ int32_t ToASCII(MaybeStackBuffer<char>* buf,
473475
&status);
474476
}
475477

476-
if (U_FAILURE(status)) {
478+
if (U_FAILURE(status) || (!lenient && info.errors != 0)) {
477479
len = -1;
478480
buf->SetLength(0);
479481
} else {
@@ -489,8 +491,11 @@ static void ToUnicode(const FunctionCallbackInfo<Value>& args) {
489491
CHECK_GE(args.Length(), 1);
490492
CHECK(args[0]->IsString());
491493
Utf8Value val(env->isolate(), args[0]);
494+
// optional arg
495+
bool lenient = args[1]->BooleanValue(env->context()).FromJust();
496+
492497
MaybeStackBuffer<char> buf;
493-
int32_t len = ToUnicode(&buf, *val, val.length());
498+
int32_t len = ToUnicode(&buf, *val, val.length(), lenient);
494499

495500
if (len < 0) {
496501
return env->ThrowError("Cannot convert name to Unicode");
@@ -508,8 +513,11 @@ static void ToASCII(const FunctionCallbackInfo<Value>& args) {
508513
CHECK_GE(args.Length(), 1);
509514
CHECK(args[0]->IsString());
510515
Utf8Value val(env->isolate(), args[0]);
516+
// optional arg
517+
bool lenient = args[1]->BooleanValue(env->context()).FromJust();
518+
511519
MaybeStackBuffer<char> buf;
512-
int32_t len = ToASCII(&buf, *val, val.length());
520+
int32_t len = ToASCII(&buf, *val, val.length(), lenient);
513521

514522
if (len < 0) {
515523
return env->ThrowError("Cannot convert name to ASCII");

src/node_i18n.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ bool InitializeICUDirectory(const std::string& path);
1818

1919
int32_t ToASCII(MaybeStackBuffer<char>* buf,
2020
const char* input,
21-
size_t length);
21+
size_t length,
22+
bool lenient = false);
2223
int32_t ToUnicode(MaybeStackBuffer<char>* buf,
2324
const char* input,
24-
size_t length);
25+
size_t length,
26+
bool lenient = false);
2527

2628
} // namespace i18n
2729
} // namespace node

0 commit comments

Comments
 (0)