Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

fix($location): don't remove multiple slashes from urls #15359

Closed

Conversation

petebacondarwin
Copy link
Contributor

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)

What is the current behavior? (You can also link to an open issue here)

What is the new behavior (if this is a feature change)?

Does this PR introduce a breaking change?

Please check if the PR fulfills these requirements

Other information:

Copy link
Contributor

@mprobst mprobst left a comment

Choose a reason for hiding this comment

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

Looks good.

locationUmlautUrl = new LocationHtml5Url('http://särver/pre/', 'http://särver/pre/', 'http://särver/pre/path');
locationIndexUrl = new LocationHtml5Url('http://server/pre/index.html', 'http://server/pre/', 'http://server/pre/path');
locationUrl = new LocationHtml5Url('http://server/pre/', 'http://server/pre/', '#!');
locationUmlautUrl = new LocationHtml5Url('http://särver/pre/', 'http://särver/pre/', '#!');
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe consider adding tests for http://server//pre/? It's not a problem in this change I think, but it might be nice to get slightly more complete test coverage.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

BTW the changes in this beforeEach were only because the setup was actually wrong! The third parameter is supposed to be the hashbang prefix.

@@ -2480,6 +2480,10 @@ describe('$location', function() {
expect(parseLinkAndReturn(locationUrl, 'someIgnoredAbsoluteHref', '#test')).toEqual('http://server/pre/otherPath#test');
});

it('should cope with double slashes in the path', function() {
expect(parseLinkAndReturn(locationUrl, 'http://server/pre///other/path')).toEqual('http://server/pre///other/path');
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if a more integration-style test that checks how the app URL is used to resolve a template would be useful? With this change, we still end up with multiple slashes in the URL, so we could still accidentally drop a path segment if we later parse it using <a href> again (not sure we do, but protecting from it would be nice).

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'll look into it...

Krzysztof also suggested that we need to deal with multiple leading backslashes too...

Copy link
Contributor

Choose a reason for hiding this comment

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

It's not just multiple backslashes. Basically \s*[\\/]{2,} would be a problem (but since in parseAppUrl / is prepended, the whitespace vector goes away, so I think changing:

for (var i = 0; url.charAt(i) === '/'; i++)
to
for (var i = 0; url.charAt(i) === '/' || url.charAt(i) === '\\' ; i++)

would be enough to fix the bug.

That said, I don't know if the multiple slashes are worth preserving in the beginning of a path for Angular apps. Existing apps served on those would be broken without this patch, so there is no backwards-compatibility problem and it's hard to tell if accepting "//" would not cause further errors when resolving relative URLs for the app later on. Prohibiting that overall seems like a good, conservative choice.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, I agree that we may as well lock this down, rather than potentially passing the issue onto some other part of the code. We can always relax this error and do something similar to this PR, later, if people complain.

// make sure path starts with '/';
if (locationObj.$$path && locationObj.$$path.charAt(0) !== '/') {
// fix up if we were passed a url with none or multiple leading slashes
if (locationObj.$$path && slashCount !== 1) {
Copy link
Member

Choose a reason for hiding this comment

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

Do we need the extra leading / for slashCount > 1?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, because it gets stripped off at some other point in the code

Copy link
Member

Choose a reason for hiding this comment

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

But don't we add it back 5 lines above with locationObj.$$path = decodeURIComponent(slashes + match.pathname.substr(1))?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's complicated. Try it! Tests will fail :-)

@petebacondarwin
Copy link
Contributor Author

petebacondarwin commented Nov 4, 2016

Closing to put a PR together that errors instead of trying to stumble along: in favour of #15365

@petebacondarwin petebacondarwin mentioned this pull request Nov 4, 2016
3 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants