-
-
Notifications
You must be signed in to change notification settings - Fork 31k
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
urljoin works incorrectly for two path-relative URLs involving . and .. #96015
Comments
According to the docs on At least as far as RFC 3986 is concerned, which is mentioned in the linked docs, the "Base URI" is also expected to be absolute. Maybe the docs could be a bit clearer. |
Even that excuse doesn’t apply to |
That indeed appears to be a more subtle case. Some clues, without a conclusion from me:
Firefox 107.0 let baseUrl1 = "http://host/a/..";
undefined
let A = new URL("b", baseUrl1);
undefined
A.href
"http://host/b"
let baseUrl2 = "../a";
undefined
let B = new URL("b", baseUrl2);
Uncaught TypeError: URL constructor: ../a is not a valid URL.
<anonymous> debugger eval code:1
debugger eval code:1:9 Chromium 107.0.5304.121 let baseUrl1 = "http://host/a/..";
undefined
let A = new URL("b", baseUrl1);
undefined
A.href
'http://host/b'
let baseUrl2 = "../a";
undefined
let B = new URL("b", baseUrl2);
VM520:1 Uncaught TypeError: Failed to construct 'URL': Invalid base URL
at <anonymous>:1:15
(anonymous) @ VM520:1 The question then is, I suppose, whether this behavior is unexpected/hard to work around enough that fixing it would be worthwhile to the point of making the risk of breaking existing code acceptable. So far I'm not aware of any standards-breaking behavior, at least. |
The expected semantics are obvious. These URLs are equivalent:
so we expect these URLs to be equvalent:
In general, we always expect:
(where Any time equivalent inputs lead to nonequivalent outputs is an opportunity for bugs. If the standard makes it optional to produce an expected result for legacy reasons, that doesn’t make it a good idea to produce an unexpected result. Another law we always expect is
which makes it obvious how
which can only work if |
Unfortunately your expectations do not align with RFC 3986. For example, for
Then
So the result should be an empty string. Currently
|
@serhiy-storchaka The RFC 3986 algorithm is defined for an absolute base URI and a relative-path reference. It does not make sense to indiscriminately apply that same algorithm to two relative-path references. §5.1:
If we are to insist on using the algorithm as written, we’d have to throw an error when the base URI is missing a scheme. However, it does make sense, and is useful in practice, to specify a generalized |
An absolute base URI can have an undefined authority and a rootless or empty path. |
Yes it can, if its scheme is defined and the parser is “strict” in the RFC sense. If we intend to behave as a strict parser, we use the RFC algorithm for that case and there is no associativity issue. A non-strict parser considers such a URI to be a relative reference. §5.4.2:
If we intend to behave as a non-strict parser, then |
Bug report
urllib.parse.urljoin
is usually used to join a normalized absolute URL with a relative URL, and it generally works for that purpose. But if it’s used to join two path-relative URLs, it produces incorrect results in many cases when.
or..
is involved.There are also some problems when the base is a non-normalized absolute URL:
Your environment
The text was updated successfully, but these errors were encountered: