From 1b7ebc238879e5642e6605b278a9dd718c7b25d7 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Wed, 9 Mar 2022 05:41:56 +0000 Subject: [PATCH] url: preserve null char in WHATWG URL errors A null character in the middle of an invalid URL was resulting in an error message that truncated the input string. This preserves the entire input string in the error message. Refs: https://github.com/nodejs/node/issues/39592 --- lib/internal/url.js | 8 +++++--- src/node_url.cc | 3 --- test/parallel/test-url-null-char.js | 8 ++++++++ 3 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 test/parallel/test-url-null-char.js diff --git a/lib/internal/url.js b/lib/internal/url.js index 41ae1b1a8be429..1b85660e07c73a 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -559,7 +559,7 @@ function onParseComplete(flags, protocol, username, password, initSearchParams(this[searchParams], query); } -function onParseError(flags, input) { +function onParseError(input, flags) { throw new ERR_INVALID_URL(input); } @@ -641,7 +641,8 @@ class URL { } this[context] = new URLContext(); parse(input, -1, base_context, undefined, - FunctionPrototypeBind(onParseComplete, this), onParseError); + FunctionPrototypeBind(onParseComplete, this), + FunctionPrototypeBind(onParseError, this, input)); } get [special]() { @@ -760,7 +761,8 @@ class URL { // toUSVString is not needed. input = `${input}`; parse(input, -1, undefined, undefined, - FunctionPrototypeBind(onParseComplete, this), onParseError); + FunctionPrototypeBind(onParseComplete, this), + FunctionPrototypeBind(onParseError, this, input)); } // readonly diff --git a/src/node_url.cc b/src/node_url.cc index 59abbe43f9917d..3859d230fa1d77 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -144,7 +144,6 @@ URLHost::~URLHost() { #define ERR_ARGS(XX) \ XX(ERR_ARG_FLAGS) \ - XX(ERR_ARG_INPUT) \ enum url_cb_args { #define XX(name) name, @@ -1681,8 +1680,6 @@ void Parse(Environment* env, } else if (error_cb->IsFunction()) { Local argv[2] = { undef, undef }; argv[ERR_ARG_FLAGS] = Integer::NewFromUnsigned(isolate, url.flags); - argv[ERR_ARG_INPUT] = - String::NewFromUtf8(env->isolate(), input).ToLocalChecked(); error_cb.As()->Call(context, recv, arraysize(argv), argv) .FromMaybe(Local()); } diff --git a/test/parallel/test-url-null-char.js b/test/parallel/test-url-null-char.js new file mode 100644 index 00000000000000..468080844d534b --- /dev/null +++ b/test/parallel/test-url-null-char.js @@ -0,0 +1,8 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +assert.throws( + () => { new URL('a\0b'); }, + { input: 'a\0b' } +);