Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement various checks on the Location setters #26231

Merged
merged 1 commit into from Apr 24, 2020

Conversation

utsavoza
Copy link
Contributor

Since there are no existing open PRs for the issue, I am raising one based on the work done by @uxioandrade and @braddunbar in previous two PRs for the issue (#25714 and #23670) respectively.

@highfive
Copy link

Heads up! This PR modifies the following files:

@highfive highfive added the S-awaiting-review There is new code that needs to be reviewed. label Apr 20, 2020
Copy link
Member

@gterzian gterzian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for figuring out all those details. I think there are a few steps missing(although you could open an issue and leave that as a follow-up if there is a reason for that), and I have a small suggestion re the set_url_component method.

Also, could you please squash into one commit? I think while it's a good idea to separate unrelated work into commits, in this case it is actually related and consolidating the work into a commit would appear clearer.

self.check_same_origin_domain()?;
// Step 3: Let copyURL be a copy of this Location object's url.
let copy_url = self.get_url();
// Step 4: If copyURL's cannot-be-a-base-URL flag is set, terminate these steps.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we doing step 5 currently? If not, I think we can do it using as_mut_url().set_path.

Copy link
Contributor Author

@utsavoza utsavoza Apr 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I assumed we were executing those steps as a part of url::quirks::set_path through UrlHelper::SetPathname, but those steps seem to correspond to dom url spec. I'll add those steps here.

// Step 3: Let copyURL be a copy of this Location object's url.
let copy_url = self.get_url();
// Step 4: If copyURL cannot have a username/password/port, then return.
// https://url.spec.whatwg.org/#cannot-have-a-username-password-port
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar re step 5, which could be done using set_port.

Copy link
Contributor Author

@utsavoza utsavoza Apr 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's one caveat though when setting port directly via as_mut_url().set_port - we'll have to manually verify and parse the input string to Option<u16>. However, we can use url::quirks::set_port to check and set the port here instead of UrlHelper::SetPort. Please let me know if I'm overlooking any better way to solve this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

// same origin-domain with the entry settings object's origin, then
// throw a "SecurityError" DOMException.
self.check_same_origin_domain()?;
self.set_url_component(value, UrlHelper::SetSearch);
Copy link
Member

@gterzian gterzian Apr 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're missing step 4 and 5 here? It looks like set_query can be used for step 4, and step 5 would be those additional manipulation of input and copyUrl before calling set_url_component.

Copy link
Contributor Author

@utsavoza utsavoza Apr 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I presumed those steps as a part of UrlHelper::SetSearch. I'll add the required steps here.

let copy_url = self.get_url();
// Step 4: If copyURL's cannot-be-a-base-URL flag is set, terminate these steps.
if !copy_url.cannot_be_a_base() {
self.set_url_component(value, UrlHelper::SetHostname);
Copy link
Member

@gterzian gterzian Apr 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we add a copy_url argument to set_url_component to avoid all those double calls to get_url(for algorithms that need the url before calling set_url_component)?

We could also add a documentation to set_url_component to note that it is supposed to match the steps related to https://url.spec.whatwg.org/#concept-basic-url-parser and https://html.spec.whatwg.org/multipage/history.html#location-object-setter-navigate, and then at the call site we could also comment to which local steps in the algorithm the call corresponds.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can actually remove the method completely - the only place we might actually need this method after adding checks would be for SetPort method probably (as we might not directly setting port to the url there). For the rest of the setters, we can directly call the navigate method with the appropriate arguments.

@utsavoza
Copy link
Contributor Author

Also, could you please squash into one commit? I think while it's a good idea to separate unrelated work into commits, in this case it is actually related and consolidating the work into a commit would appear clearer.

Agreed. I'll squash into one commit once the changes are approved.

Copy link
Member

@gterzian gterzian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a big improvement in the correctness of the implementation! Just one nit left, and then after you squash I'll approve it(after which we might still have to deal with some surprise failures on the test run).

let mut copy_url = self.get_url();
// Step 4: Let input be the given value with a single leading "#" removed, if any.
// Step 5: Set copyURL's fragment to the empty string.
// Step 6:Basic URL parse input, with copyURL as url and fragment state as
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: space missing.

// Step 3: Let copyURL be a copy of this Location object's url.
let copy_url = self.get_url();
// Step 4: If copyURL cannot have a username/password/port, then return.
// https://url.spec.whatwg.org/#cannot-have-a-username-password-port
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

@utsavoza
Copy link
Contributor Author

utsavoza commented Apr 21, 2020

Looks like a big improvement in the correctness of the implementation!

@gterzian Thanks! I have made the suggested change, and squashed all commits into one.

Just one nit left, and then after you squash I'll approve it(after which we might still have to deal with some surprise failures on the test run).

Actually, I ran the wpt tests for the location interface locally. Apart from that how do I verify if we aren't breaking anything else?

@utsavoza utsavoza force-pushed the ugo/issue-23522/16-04-2020 branch 2 times, most recently from 4b8fc42 to 79cffb3 Compare April 21, 2020 16:48
@gterzian
Copy link
Member

Actually, I ran the wpt tests for the location interface locally. Apart from that how do I verify if we aren't breaking anything else?

We have to basically run the whole suite and see, there can also be tests that unexpectedly start passing...

@gterzian
Copy link
Member

Thanks for the awesome work!

@bors-servo r+

@bors-servo
Copy link
Contributor

📌 Commit 79cffb3 has been approved by gterzian

@highfive highfive assigned gterzian and unassigned SimonSapin Apr 22, 2020
@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. labels Apr 22, 2020
@bors-servo
Copy link
Contributor

⌛ Testing commit 79cffb3 with merge 4a364f5...

bors-servo added a commit that referenced this pull request Apr 22, 2020
Implement various checks on the Location setters

Since there are no existing open PRs for the issue, I am raising one based on the work done by @uxioandrade and @braddunbar in previous two PRs for the issue (#25714 and #23670) respectively.

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #23522
- [x] There are tests for these changes
@bors-servo
Copy link
Contributor

💔 Test failed - status-taskcluster

@highfive highfive added S-tests-failed The changes caused existing tests to fail. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Apr 22, 2020
@gterzian
Copy link
Member

gterzian commented Apr 22, 2020

This one seems relevant:

1 unexpected results that are NOT known-intermittents:
  ▶ Unexpected subtest result in /html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function.html:
  │ FAIL [expected PASS] Set location from a function called from a parent
  │   → assert_equals: expected "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/source/support/location-set.html" but got "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function.html"
  │ 
  │ onload</fr.onload<@http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function.html:15:20
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:2001:25
  └ Test.prototype.step_func_done/<@http://web-platform.test:8000/resources/testharness.js:2042:32

This one does not seem relevant(I'm not sure what intermittent issue it would match by the way):

1 unexpected results that are NOT known-intermittents:
  ▶ Unexpected subtest result in /_mozilla/mozilla/scroll_top_null_target.html:
  │ FAIL [expected PASS] scroll_top_null_target
  │   → assert_equals: Target should be null! expected null but got Element node <a id="test"></a>
  │ 
  │ @http://web-platform.test:8000/_mozilla/mozilla/scroll_top_null_target.html:18:23
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:2001:25
  │ test@http://web-platform.test:8000/resources/testharness.js:548:30
  └ @http://web-platform.test:8000/_mozilla/mozilla/scroll_top_null_target.html:13:10

@gterzian
Copy link
Member

gterzian commented Apr 22, 2020

Ok the first one might actually be a new intermittent, perhaps you fixed something that makes it show up, and since it seems related to navigation, it's probably best done in a follow up. So please take a look, and if it doesn't appear to point out an issue with this PR, just file an issue for it(if there isn't one already) and add the "intermittent" label to it.

@jdm
Copy link
Member

jdm commented Apr 22, 2020

@bors-servo try=wpt

@gterzian
Copy link
Member

this one seems defenitely relevant:

  ▶ Unexpected subtest result in /url/failure.html:
  │ FAIL [expected PASS] Location's href: http:/:@/www.example.com should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ FAIL [expected PASS] Location's href: http:@/www.example.com should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ FAIL [expected PASS] Location's href: http:/@/www.example.com should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ FAIL [expected PASS] Location's href: http:a:b@/www.example.com should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ FAIL [expected PASS] Location's href: http:/a:b@/www.example.com should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ FAIL [expected PASS] Location's href: http::@/www.example.com should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ FAIL [expected PASS] Location's href: http:@:www.example.com should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ FAIL [expected PASS] Location's href: http:/@:www.example.com should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ FAIL [expected PASS] Location's href: a should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ FAIL [expected PASS] Location's href: a/ should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ FAIL [expected PASS] Location's href: a// should throw
  │   → assert_throws_js: function "() => self[0].location = test.input" did not throw
  │ 
  │ runTests/<@http://web-platform.test:8000/url/failure.html:41:23
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:2001:25
  │ test@http://web-platform.test:8000/resources/testharness.js:548:30
  └ runTests@http://web-platform.test:8000/url/failure.html:40:10

Err(e) => return Err(Error::Type(format!("Couldn't parse URL: {}", e))),
};
// Step 3: Location-object-setter navigate to the resulting URL record.
let referrer = Referrer::ReferrerUrl(base_url.clone());
Copy link
Member

@gterzian gterzian Apr 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I think this is the problem with /html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function.html, the referrer should be not from the entry document but from self.window.Document, at least that is what I make from the test failure(so it's not a new intermittent and not actually related much to navigation).

The test has a page call a method on an iframe, so the page is the "entry document" whose url would be the base url, however the referrer should still be url of the iframe itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, right. The referrer url shouldn't be from entry document here - I think let referrer = Referrer::ReferrerUrl(self.get_url()); should fix this.

@utsavoza
Copy link
Contributor Author

I was able to find six relevant test failures:

  1. /url/failure.html
  2. /html/browsers/browsing-the-web/navigating-across-documents/005.html
  3. /html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function.html
  4. /html/browsers/browsing-the-web/navigating-across-documents/empty_fragment.html
  5. /html/browsers/browsing-the-web/unloading-documents/beforeunload-synchronous.html - [UNEXPECTED PASS]
  6. /fullscreen/api/document-exit-fullscreen-active-document.html - [UNEXPECTED PASS]

and one NOT known-intermittent (as pointed out by @gterzian) from the logs:

./mach filter-intermittents wpt-jsonsummary.log --log-intermittents intermittents.log --log-filteredsummary filtered-wpt-errorsummary.log --tracker-api default --reporter-api default
1 unexpected results that are NOT known-intermittents:
  ▶ Unexpected subtest result in /_mozilla/mozilla/scroll_top_null_target.html:
  │ FAIL [expected PASS] scroll_top_null_target
  │   → assert_equals: Target should be null! expected null but got Element node <a id="test"></a>
  │
  │ @http://web-platform.test:8000/_mozilla/mozilla/scroll_top_null_target.html:18:23
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:2001:25
  │ test@http://web-platform.test:8000/resources/testharness.js:548:30
  └ @http://web-platform.test:8000/_mozilla/mozilla/scroll_top_null_target.html:13:10

I will try to resolve these and post any updates here.

@jdm
Copy link
Member

jdm commented Apr 22, 2020

Filed #26269 for the new unrelated intermittent test result.

@gterzian
Copy link
Member

@utsavoza awesome, sounds like it's worth updating this PR with your work and we'll give the test suite another try...

Implement various checks on the Location setters

Set correct referrer url before for href location setter

Update wpt-metadata for failing tests

Try updating tests/wpt/metadata/url/failure.html.ini
@utsavoza
Copy link
Contributor Author

Done!

@gterzian
Copy link
Member

@utsavoza Thanks for completing this, it was a lot of additional work in the end!

@bors-servo r+

@bors-servo
Copy link
Contributor

📌 Commit b10de77 has been approved by gterzian

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. S-needs-rebase There are merge conflict errors. labels Apr 24, 2020
@bors-servo
Copy link
Contributor

⌛ Testing commit b10de77 with merge bd86ff8...

bors-servo added a commit that referenced this pull request Apr 24, 2020
Implement various checks on the Location setters

Since there are no existing open PRs for the issue, I am raising one based on the work done by @uxioandrade and @braddunbar in previous two PRs for the issue (#25714 and #23670) respectively.

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #23522
- [x] There are tests for these changes
@bors-servo
Copy link
Contributor

💔 Test failed - status-taskcluster

@highfive highfive added S-tests-failed The changes caused existing tests to fail. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Apr 24, 2020
@gterzian
Copy link
Member

gterzian commented Apr 24, 2020

bors-servo added a commit that referenced this pull request Apr 24, 2020
Implement various checks on the Location setters

Since there are no existing open PRs for the issue, I am raising one based on the work done by @uxioandrade and @braddunbar in previous two PRs for the issue (#25714 and #23670) respectively.

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #23522
- [x] There are tests for these changes
@bors-servo
Copy link
Contributor

⌛ Testing commit b10de77 with merge 0123fed...

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-tests-failed The changes caused existing tests to fail. labels Apr 24, 2020
@bors-servo
Copy link
Contributor

💔 Test failed - status-taskcluster

@highfive highfive added S-tests-failed The changes caused existing tests to fail. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Apr 24, 2020
@bors-servo
Copy link
Contributor

⌛ Testing commit b10de77 with merge 3078b35...

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-tests-failed The changes caused existing tests to fail. labels Apr 24, 2020
@bors-servo
Copy link
Contributor

☀️ Test successful - status-taskcluster
Approved by: gterzian
Pushing 3078b35 to master...

@bors-servo bors-servo merged commit 3078b35 into servo:master Apr 24, 2020
@highfive highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Apr 24, 2020
@utsavoza
Copy link
Contributor Author

@utsavoza Thanks for completing this, it was a lot of additional work in the end!

Hey @gterzian, thanks for your guidance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement various checks on the Location setters
7 participants