You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
urljoining an empty query string doesn't clear query string #76960
I'm working on a patch for this and can have one up in the next week or so, once I get the CLA signed and other boxes ticked. I'm new to the Github process but hopefully it will be a good start for the discussion.
In this case, the RFC is mismatched from the actual behaviour of browsers (as described and codified by WhatWG). It was surprising to me that urljoin() didn't do what I percieved as "the right thing" (and I expect other users would too).
I would personally expect urljoin to do "the thing that everybody else does". Is there a sensible way to reduce this mismatch?
For reference, Java's stdlib does what I would expect here:
URI base = URI.create("https://example.com/?a=b");
URI rel = base.resolve("?");
System.out.println(rel);
Sorry, urlparse returns '' rather than None when there is no query.
So we indeed need to check something like
if '?' not in url:
or what's in Paul's patch.
However, my main point was to question whether fixing this is actually in contradiction with the RFC.
thetorpedodog commented on May 28, 2021
thetorpedodogmannequin
MannequinAuthor
More actions
Reading more into this, from section 5.2,1:
A component is undefined if its associated delimiter does not appear in the URI reference
So you could say that since there is a '?', the query component is *defined*, but *empty*. This would mean that assigning the target query to be '' has the desired effect as implemented by browsers and other languages' standard libraries.
Python 3.12.0a7+ (heads/main:4898415df7, Apr 20 2023, 16:46:44) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib.parse
>>> urllib.parse.urljoin("http://www.example.com/?a/b","?")
'http://www.example.com/?a/b'
We can treat this as bug and fix it. However, there are very high chances that people are relying on the current no-op behavior, and this change in behavior can cause frameworks to break. This sounds a bit costly to me.
RFC3986 does not define "params". The URI consists of 5 components: scheme, authority, path, query, fragment. '/b/c/d;' is the path, and the urllib functions mutilate it.
This is why I think that it is worth to backport the solution.
True. And when I dug a bit into this topic yesterday. Using params is highly discouraged now, and I think, very old Sun Servers and FTPs used a params for storing session state
The backport is fine. But it carries the risk of breaking some applications. Calling it out and early backport is alright IMO.
Activity
thetorpedodog commentedon Feb 6, 2018
urljoining with '?' will not clear a query string:
EXPECTED:
'http://a/b/c' (optionally, with a ? at the end)
WhatWG's URL standard expects a relative URL consisting of only a ? to replace a query string:
https://url.spec.whatwg.org/#relative-state
Seen in versions 3.6 and 2.7, but probably also affects later versions.
thetorpedodog commentedon Feb 10, 2018
I'm working on a patch for this and can have one up in the next week or so, once I get the CLA signed and other boxes ticked. I'm new to the Github process but hopefully it will be a good start for the discussion.
asvetlov commentedon Feb 15, 2018
Python follows not WhatWG but RFC.
https://tools.ietf.org/html/rfc3986#section-5.2.2 is proper definition for url joining algorithm.
thetorpedodog commentedon Feb 15, 2018
In this case, the RFC is mismatched from the actual behaviour of browsers (as described and codified by WhatWG). It was surprising to me that urljoin() didn't do what I percieved as "the right thing" (and I expect other users would too).
I would personally expect urljoin to do "the thing that everybody else does". Is there a sensible way to reduce this mismatch?
For reference, Java's stdlib does what I would expect here:
https://example.com/?
iritkatriel commentedon May 28, 2021
The relevant part in the RFC pseudo code is
which is implemented in urljoin as:
Is this correct? Should the code not say "if query is not None"?
(I can't see in the RFC a definition of defined()).
iritkatriel commentedon May 28, 2021
Sorry, urlparse returns '' rather than None when there is no query.
So we indeed need to check something like
if '?' not in url:
or what's in Paul's patch.
However, my main point was to question whether fixing this is actually in contradiction with the RFC.
thetorpedodog commentedon May 28, 2021
Reading more into this, from section 5.2,1:
So you could say that since there is a '?', the query component is *defined*, but *empty*. This would mean that assigning the target query to be '' has the desired effect as implemented by browsers and other languages' standard libraries.
orsenthil commentedon Apr 21, 2023
Yes, this a bug with urljoin in Python.
I compared the behavior against Ruby, and Golang.
Output:
And go's https://pkg.go.dev/net/url@go1.19beta1#URL.ResolveReference, ResolveReference resolves a URI reference to an absolute URI from an absolute base URI u, per RFC 3986 Section 5.2.
In python
We can treat this as bug and fix it. However, there are very high chances that people are relying on the current no-op behavior, and this change in behavior can cause frameworks to break. This sounds a bit costly to me.
pythongh-76960: Fix urljoin() and urldefrag() for URIs with empty com…
3 remaining items
gh-76960: Fix urljoin() and urldefrag() for URIs with empty components (
serhiy-storchaka commentedon Aug 31, 2024
Yet one bug (and perhaps more serious one) -- removing trailing semicolon from the path.
RFC3986 does not define "params". The URI consists of 5 components: scheme, authority, path, query, fragment.
'/b/c/d;'is the path, and theurllibfunctions mutilate it.This is why I think that it is worth to backport the solution.
orsenthil commentedon Sep 1, 2024
True. And when I dug a bit into this topic yesterday. Using params is highly discouraged now, and I think, very old Sun Servers and FTPs used a params for storing session state
The backport is fine. But it carries the risk of breaking some applications. Calling it out and early backport is alright IMO.
Start PostgreSQL URI path with a '/'
Start PostgreSQL URI path with a '/'
Start PostgreSQL URI path with a '/'
Start PostgreSQL URI path with a '/'
serhiy-storchaka commentedon Nov 11, 2024
Should this change be backported?
hugovk commentedon Jan 7, 2025
Triage: if we're not backporting, let's close this.