Skip to content

Fix double decoding of URL query values - #4209

Open
winklemad wants to merge 1 commit into
redis:masterfrom
winklemad:fix/parse-url-query-double-decode-c2
Open

Fix double decoding of URL query values#4209
winklemad wants to merge 1 commit into
redis:masterfrom
winklemad:fix/parse-url-query-double-decode-c2

Conversation

@winklemad

@winklemad winklemad commented Jul 26, 2026

Copy link
Copy Markdown

Description of change

urllib.parse.parse_qs already percent-decodes query values. Both the sync and
async URL parsers subsequently called unquote on those values, causing
doubly encoded data such as %2520 to become a space instead of the literal
%20.

Remove the redundant second decoding step in both implementations and add
mirrored sync/async regression tests proving query values are decoded exactly
once.

Fixes #4208

Pull Request check-list

Please make sure to review and check all of these items:

  • Do tests and lints pass with this change?
    • Focused tests, all 83 URL-parsing tests, Ruff checks and formatting for
      changed files, and full Vulture pass.
    • The repository-wide formatter check reports three pre-existing unrelated
      files on master.
  • Do the CI tests pass with this change (enable it first in your forked repo and wait for the github action build to finish)?
    • CI has not run yet.
  • Is the new or changed code fully tested?
  • Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?
    • Not applicable; no public API is modified.
  • Is there an example added to the examples folder (if applicable)?
    • Not applicable.

NOTE: these things are not required to open a PR and can be done
afterwards / while the PR is open.


Note

Low Risk
Small, localized URL parsing fix with mirrored tests; no auth or API surface changes beyond correct query string values.

Overview
Fixes double percent-decoding of connection URL query parameters in sync and async parse_url by dropping an extra unquote() on values returned from parse_qs, which already decodes them once.

Values like client_name=worker%2520name now become the literal worker%20name instead of worker name. Username, password, path, and host handling are unchanged and still use unquote where appropriate.

Adds matching sync/async pool tests (test_querystring_values_are_decoded_once) to lock in single-decode behavior (fixes #4208).

Reviewed by Cursor Bugbot for commit 6a5dbf3. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread redis/connection.py
for name, value in parse_qs(url.query).items():
if value and len(value) > 0:
value = unquote(value[0])
value = value[0]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this contradicts the from_url docstrings, which state "The username, password, hostname, path and all querystring values are passed through urllib.parse.unquote". Same text lives in client.py:185, cluster.py:660, asyncio/client.py:172 and asyncio/cluster.py:344, so all four need the querystring part dropped or this becomes an undocumented behavior change for anyone who double-encoded on purpose.

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.

URL query values are percent-decoded twice

2 participants