Browse Source

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: https://github.com/nodejs/node/pull/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>
v6
Timothy Gu 8 years ago
parent
commit
c2a302c50b
  1. 5
      lib/url.js
  2. 20
      src/node_i18n.cc
  3. 6
      src/node_i18n.h

5
lib/url.js

@ -319,7 +319,10 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
// It only converts parts of the domain name that // It only converts parts of the domain name that
// have non-ASCII characters, i.e. it doesn't matter if // have non-ASCII characters, i.e. it doesn't matter if
// you call it with a domain that already is ASCII-only. // 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 : ''; var p = this.port ? ':' + this.port : '';

20
src/node_i18n.cc

@ -410,7 +410,8 @@ bool InitializeICUDirectory(const std::string& path) {
int32_t ToUnicode(MaybeStackBuffer<char>* buf, int32_t ToUnicode(MaybeStackBuffer<char>* buf,
const char* input, const char* input,
size_t length) { size_t length,
bool lenient) {
UErrorCode status = U_ZERO_ERROR; UErrorCode status = U_ZERO_ERROR;
uint32_t options = UIDNA_DEFAULT; uint32_t options = UIDNA_DEFAULT;
options |= UIDNA_NONTRANSITIONAL_TO_UNICODE; options |= UIDNA_NONTRANSITIONAL_TO_UNICODE;
@ -435,7 +436,7 @@ int32_t ToUnicode(MaybeStackBuffer<char>* buf,
&status); &status);
} }
if (U_FAILURE(status)) { if (U_FAILURE(status) || (!lenient && info.errors != 0)) {
len = -1; len = -1;
buf->SetLength(0); buf->SetLength(0);
} else { } else {
@ -448,7 +449,8 @@ int32_t ToUnicode(MaybeStackBuffer<char>* buf,
int32_t ToASCII(MaybeStackBuffer<char>* buf, int32_t ToASCII(MaybeStackBuffer<char>* buf,
const char* input, const char* input,
size_t length) { size_t length,
bool lenient) {
UErrorCode status = U_ZERO_ERROR; UErrorCode status = U_ZERO_ERROR;
uint32_t options = UIDNA_DEFAULT; uint32_t options = UIDNA_DEFAULT;
options |= UIDNA_NONTRANSITIONAL_TO_ASCII; options |= UIDNA_NONTRANSITIONAL_TO_ASCII;
@ -473,7 +475,7 @@ int32_t ToASCII(MaybeStackBuffer<char>* buf,
&status); &status);
} }
if (U_FAILURE(status)) { if (U_FAILURE(status) || (!lenient && info.errors != 0)) {
len = -1; len = -1;
buf->SetLength(0); buf->SetLength(0);
} else { } else {
@ -489,8 +491,11 @@ static void ToUnicode(const FunctionCallbackInfo<Value>& args) {
CHECK_GE(args.Length(), 1); CHECK_GE(args.Length(), 1);
CHECK(args[0]->IsString()); CHECK(args[0]->IsString());
Utf8Value val(env->isolate(), args[0]); Utf8Value val(env->isolate(), args[0]);
// optional arg
bool lenient = args[1]->BooleanValue(env->context()).FromJust();
MaybeStackBuffer<char> buf; MaybeStackBuffer<char> buf;
int32_t len = ToUnicode(&buf, *val, val.length()); int32_t len = ToUnicode(&buf, *val, val.length(), lenient);
if (len < 0) { if (len < 0) {
return env->ThrowError("Cannot convert name to Unicode"); return env->ThrowError("Cannot convert name to Unicode");
@ -508,8 +513,11 @@ static void ToASCII(const FunctionCallbackInfo<Value>& args) {
CHECK_GE(args.Length(), 1); CHECK_GE(args.Length(), 1);
CHECK(args[0]->IsString()); CHECK(args[0]->IsString());
Utf8Value val(env->isolate(), args[0]); Utf8Value val(env->isolate(), args[0]);
// optional arg
bool lenient = args[1]->BooleanValue(env->context()).FromJust();
MaybeStackBuffer<char> buf; MaybeStackBuffer<char> buf;
int32_t len = ToASCII(&buf, *val, val.length()); int32_t len = ToASCII(&buf, *val, val.length(), lenient);
if (len < 0) { if (len < 0) {
return env->ThrowError("Cannot convert name to ASCII"); return env->ThrowError("Cannot convert name to ASCII");

6
src/node_i18n.h

@ -18,10 +18,12 @@ bool InitializeICUDirectory(const std::string& path);
int32_t ToASCII(MaybeStackBuffer<char>* buf, int32_t ToASCII(MaybeStackBuffer<char>* buf,
const char* input, const char* input,
size_t length); size_t length,
bool lenient = false);
int32_t ToUnicode(MaybeStackBuffer<char>* buf, int32_t ToUnicode(MaybeStackBuffer<char>* buf,
const char* input, const char* input,
size_t length); size_t length,
bool lenient = false);
} // namespace i18n } // namespace i18n
} // namespace node } // namespace node

Loading…
Cancel
Save