diff --git a/doc/api/errors.md b/doc/api/errors.md index fcc39ab2ac81ee..498fc856ad5b19 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1116,6 +1116,11 @@ API] [`URLSearchParams` constructor][`new URLSearchParams(iterable)`] does not represent a `[name, value]` tuple – that is, if an element is not iterable, or does not consist of exactly two elements. + +### ERR_INVALID_URI + +Used when an invalid URI is passed. + ### ERR_INVALID_URL diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 9bf0951eece120..fc6b11a40e9d1f 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -126,6 +126,7 @@ module.exports = exports = { Error: makeNodeError(Error), TypeError: makeNodeError(TypeError), RangeError: makeNodeError(RangeError), + URIError: makeNodeError(URIError), AssertionError, E // This is exported only to facilitate testing. }; @@ -287,6 +288,7 @@ E('ERR_INVALID_SYNC_FORK_INPUT', 'Asynchronous forks do not support Buffer, Uint8Array or string input: %s'); E('ERR_INVALID_THIS', 'Value of "this" must be of type %s'); E('ERR_INVALID_TUPLE', '%s must be an iterable %s tuple'); +E('ERR_INVALID_URI', 'URI malformed'); E('ERR_INVALID_URL', 'Invalid URL: %s'); E('ERR_INVALID_URL_SCHEME', (expected) => `The URL must be ${oneOf(expected, 'scheme')}`); diff --git a/lib/querystring.js b/lib/querystring.js index 936b7463c9e5f6..ec6ad51a89177e 100644 --- a/lib/querystring.js +++ b/lib/querystring.js @@ -24,6 +24,7 @@ 'use strict'; const { Buffer } = require('buffer'); +const errors = require('internal/errors'); const { hexTable, isHexTable @@ -174,11 +175,12 @@ function qsEscape(str) { } // Surrogate pair ++i; - var c2; - if (i < str.length) - c2 = str.charCodeAt(i) & 0x3FF; - else - throw new URIError('URI malformed'); + + if (i >= str.length) + throw new errors.URIError('ERR_INVALID_URI'); + + var c2 = str.charCodeAt(i) & 0x3FF; + lastPos = i + 1; c = 0x10000 + (((c & 0x3FF) << 10) | c2); out += hexTable[0xF0 | (c >> 18)] + diff --git a/test/parallel/test-querystring-escape.js b/test/parallel/test-querystring-escape.js index fd20a8424fee96..18bece1ab13288 100644 --- a/test/parallel/test-querystring-escape.js +++ b/test/parallel/test-querystring-escape.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const qs = require('querystring'); @@ -12,8 +12,15 @@ assert.deepStrictEqual(qs.escape('Ŋōđĕ'), '%C5%8A%C5%8D%C4%91%C4%95'); assert.deepStrictEqual(qs.escape('testŊōđĕ'), 'test%C5%8A%C5%8D%C4%91%C4%95'); assert.deepStrictEqual(qs.escape(`${String.fromCharCode(0xD800 + 1)}test`), '%F0%90%91%B4est'); -assert.throws(() => qs.escape(String.fromCharCode(0xD800 + 1)), - /^URIError: URI malformed$/); + +common.expectsError( + () => qs.escape(String.fromCharCode(0xD800 + 1)), + { + code: 'ERR_INVALID_URI', + type: URIError, + message: 'URI malformed' + } +); // using toString for objects assert.strictEqual( diff --git a/test/parallel/test-querystring.js b/test/parallel/test-querystring.js index ed0138e07937ef..400431fd2cb132 100644 --- a/test/parallel/test-querystring.js +++ b/test/parallel/test-querystring.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const inspect = require('util').inspect; @@ -271,9 +271,14 @@ qsWeirdObjects.forEach(function(testCase) { }); // invalid surrogate pair throws URIError -assert.throws(function() { - qs.stringify({ foo: '\udc00' }); -}, /^URIError: URI malformed$/); +common.expectsError( + () => qs.stringify({ foo: '\udc00' }), + { + code: 'ERR_INVALID_URI', + type: URIError, + message: 'URI malformed' + } +); // coerce numbers to string assert.strictEqual('foo=0', qs.stringify({ foo: 0 }));