diff --git a/src/bun.js/bindings/ErrorCode.cpp b/src/bun.js/bindings/ErrorCode.cpp index 2d9142401f..26d7664ef5 100644 --- a/src/bun.js/bindings/ErrorCode.cpp +++ b/src/bun.js/bindings/ErrorCode.cpp @@ -47,6 +47,9 @@ static JSC::JSObject* createErrorPrototype(JSC::VM& vm, JSC::JSGlobalObject* glo case JSC::ErrorType::Error: prototype = JSC::constructEmptyObject(globalObject, globalObject->errorPrototype()); break; + case JSC::ErrorType::URIError: + prototype = JSC::constructEmptyObject(globalObject, globalObject->m_URIErrorStructure.prototype(globalObject)); + break; default: { RELEASE_ASSERT_NOT_REACHED_WITH_MESSAGE("TODO: Add support for more error types"); break; diff --git a/src/bun.js/bindings/ErrorCode.ts b/src/bun.js/bindings/ErrorCode.ts index a2184f7215..59f71ba69f 100644 --- a/src/bun.js/bindings/ErrorCode.ts +++ b/src/bun.js/bindings/ErrorCode.ts @@ -46,6 +46,7 @@ export default [ ["ERR_UNKNOWN_SIGNAL", TypeError, "TypeError"], ["ERR_SOCKET_BAD_PORT", RangeError, "RangeError"], ["ERR_STREAM_RELEASE_LOCK", Error, "AbortError"], + ["ERR_INVALID_URI", URIError, "URIError"], // Bun-specific ["ERR_FORMDATA_PARSE_ERROR", TypeError, "TypeError"], diff --git a/src/js/node/querystring.ts b/src/js/node/querystring.ts index 73a9a0ac15..3d2a57f535 100644 --- a/src/js/node/querystring.ts +++ b/src/js/node/querystring.ts @@ -141,7 +141,7 @@ var require_src = __commonJS((exports, module) => { ++i2; var c2; if (i2 < str.length) c2 = str.charCodeAt(i2) & 1023; - else throw new URIError("URI malformed"); + else throw $ERR_INVALID_URI("URI malformed"); lastPos = i2 + 1; c = 65536 + (((c & 1023) << 10) | c2); out += diff --git a/test/js/node/test/parallel/test-querystring-escape.js b/test/js/node/test/parallel/test-querystring-escape.js new file mode 100644 index 0000000000..5f3ea3aedc --- /dev/null +++ b/test/js/node/test/parallel/test-querystring-escape.js @@ -0,0 +1,41 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +const qs = require('querystring'); + +assert.strictEqual(qs.escape(5), '5'); +assert.strictEqual(qs.escape('test'), 'test'); +assert.strictEqual(qs.escape({}), '%5Bobject%20Object%5D'); +assert.strictEqual(qs.escape([5, 10]), '5%2C10'); +assert.strictEqual(qs.escape('Ŋōđĕ'), '%C5%8A%C5%8D%C4%91%C4%95'); +assert.strictEqual(qs.escape('testŊōđĕ'), 'test%C5%8A%C5%8D%C4%91%C4%95'); +assert.strictEqual(qs.escape(`${String.fromCharCode(0xD800 + 1)}test`), + '%F0%90%91%B4est'); + +assert.throws( + () => qs.escape(String.fromCharCode(0xD800 + 1)), + { + code: 'ERR_INVALID_URI', + name: 'URIError', + message: 'URI malformed' + } +); + +// Using toString for objects +assert.strictEqual( + qs.escape({ test: 5, toString: () => 'test', valueOf: () => 10 }), + 'test' +); + +// `toString` is not callable, must throw an error. +// Error message will vary between different JavaScript engines, so only check +// that it is a `TypeError`. +assert.throws(() => qs.escape({ toString: 5 }), TypeError); + +// Should use valueOf instead of non-callable toString. +assert.strictEqual(qs.escape({ toString: 5, valueOf: () => 'test' }), 'test'); + +// Error message will vary between different JavaScript engines, so only check +// that it is a `TypeError`. +assert.throws(() => qs.escape(Symbol('test')), TypeError);