From 9d9be6184683ee068569f03cf29d0c0c852d12e8 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Wed, 7 Nov 2018 15:58:51 +0800 Subject: [PATCH] url: make the context non-enumerable At the moment we expose the context as a normal property on the prototype chain of URL or take them from the base URL which makes them enumerable and considered by assert libraries even though the context carries path-dependent information that do not affect the equivalence of these objects. This patch fixes it in a minimal manner by marking the context non-enumerable as making it full private would require more refactoring and can be done in a bigger patch later. --- lib/internal/url.js | 15 +++++++++++++-- ...est-whatwg-url-custom-no-enumerable-context.js | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-whatwg-url-custom-no-enumerable-context.js diff --git a/lib/internal/url.js b/lib/internal/url.js index 518c745b41e760..693f082aed6137 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -245,7 +245,14 @@ function onParseError(flags, input) { // Reused by URL constructor and URL#href setter. function parse(url, input, base) { const base_context = base ? base[context] : undefined; - url[context] = new URLContext(); + // In the URL#href setter + if (!url[context]) { + Object.defineProperty(url, context, { + enumerable: false, + configurable: false, + value: new URLContext() + }); + } _parse(input.trim(), -1, base_context, undefined, onParseComplete.bind(url), onParseError); } @@ -1437,7 +1444,11 @@ function toPathIfFileURL(fileURLOrPath) { } function NativeURL(ctx) { - this[context] = ctx; + Object.defineProperty(this, context, { + enumerable: false, + configurable: false, + value: ctx + }); } NativeURL.prototype = URL.prototype; diff --git a/test/parallel/test-whatwg-url-custom-no-enumerable-context.js b/test/parallel/test-whatwg-url-custom-no-enumerable-context.js new file mode 100644 index 00000000000000..f24a47b6d5c8f0 --- /dev/null +++ b/test/parallel/test-whatwg-url-custom-no-enumerable-context.js @@ -0,0 +1,14 @@ +'use strict'; +// This tests that the context of URL objects are not +// enumerable and thus considered by assert libraries. +// See https://github.com/nodejs/node/issues/24211 + +// Tests below are not from WPT. + +require('../common'); +const assert = require('assert'); + +assert.deepStrictEqual( + new URL('./foo', 'https://example.com/'), + new URL('https://example.com/foo') +);