From 0e88f445471ea02a904e03ad06d48e8e608215e1 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Tue, 13 Nov 2018 15:31:44 -0800 Subject: [PATCH] src: set HAS_USERNAME/PASSWORD more strictly Fixes: https://github.com/nodejs/node/issues/24211 PR-URL: https://github.com/nodejs/node/pull/24495 Reviewed-By: Anna Henningsen Reviewed-By: Joyee Cheung Reviewed-By: Gus Caplan Reviewed-By: Franziska Hinkelmann Reviewed-By: Daijiro Wachi Reviewed-By: Ruben Bridgewater Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- src/node_url.cc | 28 +++++++++++++------ .../test-whatwg-url-custom-deepequal.js | 18 ++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 test/parallel/test-whatwg-url-custom-deepequal.js diff --git a/src/node_url.cc b/src/node_url.cc index 9eec9dc16691d3..39007f9523390f 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -1209,21 +1209,33 @@ inline url_data HarvestBase(Environment* env, Local base_obj) { base_obj->Get(env->context(), env->scheme_string()).ToLocalChecked(); base.scheme = Utf8Value(env->isolate(), scheme).out(); - auto GetStr = [&](std::string url_data::* member, + auto GetStr = [&](std::string url_data::*member, int flag, - Local name) { + Local name, + bool empty_as_present) { Local value = base_obj->Get(env->context(), name).ToLocalChecked(); if (value->IsString()) { Utf8Value utf8value(env->isolate(), value.As()); (base.*member).assign(*utf8value, utf8value.length()); - base.flags |= flag; + if (empty_as_present || value.As()->Length() != 0) { + base.flags |= flag; + } } }; - GetStr(&url_data::username, URL_FLAGS_HAS_USERNAME, env->username_string()); - GetStr(&url_data::password, URL_FLAGS_HAS_PASSWORD, env->password_string()); - GetStr(&url_data::host, URL_FLAGS_HAS_HOST, env->host_string()); - GetStr(&url_data::query, URL_FLAGS_HAS_QUERY, env->query_string()); - GetStr(&url_data::fragment, URL_FLAGS_HAS_FRAGMENT, env->fragment_string()); + GetStr(&url_data::username, + URL_FLAGS_HAS_USERNAME, + env->username_string(), + false); + GetStr(&url_data::password, + URL_FLAGS_HAS_PASSWORD, + env->password_string(), + false); + GetStr(&url_data::host, URL_FLAGS_HAS_HOST, env->host_string(), true); + GetStr(&url_data::query, URL_FLAGS_HAS_QUERY, env->query_string(), true); + GetStr(&url_data::fragment, + URL_FLAGS_HAS_FRAGMENT, + env->fragment_string(), + true); Local port = base_obj->Get(env->context(), env->port_string()).ToLocalChecked(); diff --git a/test/parallel/test-whatwg-url-custom-deepequal.js b/test/parallel/test-whatwg-url-custom-deepequal.js new file mode 100644 index 00000000000000..9150b1561b7c77 --- /dev/null +++ b/test/parallel/test-whatwg-url-custom-deepequal.js @@ -0,0 +1,18 @@ +'use strict'; +// This tests that the internal flags in URL objects are consistent, as manifest +// through 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') +); +assert.deepStrictEqual( + new URL('./foo', 'https://user:pass@example.com/'), + new URL('https://user:pass@example.com/foo') +);