+++ /dev/null
-.. change::
- :tags: bug, engine
- :tickets: 10662
-
- Fixed URL-encoding of the username and password components of
- :class:`.engine.URL` objects when converting them to string using the
- :meth:`_engine.URL.render_as_string` method, by using Python standard
- library ``urllib.parse.quote_plus``, rather than the legacy home-grown
- routine from many years ago. Pull request courtesy of Xavier NUNN.
s += "@"
if self.host is not None:
if ":" in self.host:
- s += f"[{self.host}]"
+ s += "[%s]" % self.host
else:
s += self.host
if self.port is not None:
keys = list(self.query)
keys.sort()
s += "?" + "&".join(
- f"{_sqla_url_quote(k)}={_sqla_url_quote(element)}"
+ "%s=%s" % (quote_plus(k), quote_plus(element))
for k in keys
for element in util.to_list(self.query[k])
)
)
-_sqla_url_quote = quote_plus
+def _sqla_url_quote(text: str) -> str:
+ return re.sub(r"[:@/]", lambda m: "%%%X" % ord(m.group(0)), text)
_sqla_url_unquote = unquote
"dbtype://username:password@hostspec/test database with@atsign",
"dbtype://username:password@hostspec?query=but_no_db",
"dbtype://username:password@hostspec:450?query=but_no_db",
- "dbtype://user%25%26%7C:pass%25%26%7C@hostspec:499?query=but_no_db",
)
def test_rfc1738(self, text):
u = url.make_url(text)
assert u.drivername in ("dbtype", "dbtype+apitype")
- assert u.username in ("username", "user%&|", None)
- assert u.password in (
- "password",
- "apples/oranges",
- "pass%&|",
- None,
- )
+ assert u.username in ("username", None)
+ assert u.password in ("password", "apples/oranges", None)
assert u.host in (
"hostspec",
"127.0.0.1",
eq_(str(u), "dbtype://user:***@host/dbname")
eq_(
u.render_as_string(hide_password=False),
- "dbtype://user:pass+word+%2B+other%3Awords@host/dbname",
+ "dbtype://user:pass word + other%3Awords@host/dbname",
)
u = url.make_url(