Skip to content

fix(clickhouse): sanitize brackets in connection-URL userinfo before parse - #2454

Merged
goldmedal merged 2 commits into
Canner:mainfrom
Bartok9:fix/clickhouse-url-brackets
Jul 13, 2026
Merged

fix(clickhouse): sanitize brackets in connection-URL userinfo before parse#2454
goldmedal merged 2 commits into
Canner:mainfrom
Bartok9:fix/clickhouse-url-brackets

Conversation

@Bartok9

@Bartok9 Bartok9 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Sanitize raw [ / ] in ClickHouse connection-URL userinfo before urlparse.
  • Preserve legitimate IPv6 hosts that still need brackets around the host.

Motivation

urlparse treats [ / ] anywhere in the netloc as IPv6 delimiters. A password like p[a]ss therefore raises ValueError: Invalid IPv6 URL and the connector never opens. Same root cause already fixed for MySQL / MSSQL / Oracle on this tree — ClickHouse was still on bare urlparse.

Verification

  • PYTHONPATH=src pytest tests/unit/test_clickhouse_helpers.py50 passed
  • Regression tests:
    • test_clickhouse_url_allows_raw_brackets_in_password
    • test_clickhouse_url_preserves_ipv6_host_with_bracketed_password
  • Real behavior without fix: clickhouse://user:p[a]ss@host:9000/dbValueError: Invalid IPv6 URL
  • With fix: username user, password p[a]ss, host intact; clickhouse://user:p[a]ss@[::1]:9000/db keeps host ::1.
  • Did NOT change decoding of %-encoded characters, unquote_plus credential handling, secure-port defaults, or query wrapping.

License

core/wren/** only (Apache-2.0).

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of ClickHouse connection URLs when credentials include special characters like [ or ], preventing URL parsing failures.
    • Ensured IPv6 host addresses are parsed correctly while continuing to extract the right username and password from the URL.
  • Tests
    • Added unit test coverage for bracketed credentials and IPv6 host edge cases in ClickHouse URL parsing.

…parse

clickhouse:// URLs with '[' or ']' in credentials raised ValueError from
urlparse's IPv6 netloc check, so such connections could never be opened.
Mirror the MySQL connector's userinfo sanitiser so bracketed credentials
parse while real IPv6 hosts still work.
@github-actions github-actions Bot added python Pull requests that update Python code core labels Jul 9, 2026
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 372b83d2-5c7c-48ee-8fed-2f218497c05c

📥 Commits

Reviewing files that changed from the base of the PR and between 8db4a3e and c1fc1cb.

📒 Files selected for processing (1)
  • core/wren/src/wren/connector/clickhouse.py
💤 Files with no reviewable changes (1)
  • core/wren/src/wren/connector/clickhouse.py

Walkthrough

Adds a ClickHouse connection URL helper that percent-encodes brackets in userinfo before parsing, updates client-kwargs construction to use it, and adds unit tests for bracketed passwords and IPv6 host literals.

Changes

ClickHouse URL parsing fix

Layer / File(s) Summary
Sanitized URL parsing and wiring
core/wren/src/wren/connector/clickhouse.py
New _parse_clickhouse_connection_url escapes [/] within userinfo before re-parsing, and _build_clickhouse_client_kwargs now uses it in the URL-based branch.
Bracketed password and IPv6 host tests
core/wren/tests/unit/test_clickhouse_helpers.py
New tests confirm bracket-containing passwords parse without errors and that IPv6 host literals ([::1]) with bracketed passwords yield the expected username, password, and host.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • Canner/WrenAI#2412: Also modifies URL-handling logic in _build_clickhouse_client_kwargs, changing scheme-based secure/default-port selection.

Suggested reviewers: goldmedal

Poem

A bunny hopped through brackets bright,
and userinfo parsed just right.
[ and ] no longer clash,
IPv6 stays in the hash,
and tests proclaim the fix holds tight 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main ClickHouse URL parsing fix involving bracket sanitization in userinfo.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (2)
core/wren/tests/unit/test_clickhouse_helpers.py (1)

398-414: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider placing new tests inside TestClickHouseUrlKwargs for consistency.

The two new test functions are module-level, while all other URL-parsing tests in this file are methods of the TestClickHouseUrlKwargs class (line 242). Moving them into the class would keep the test organization consistent and allow them to be collected under the same test class in reports.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/wren/tests/unit/test_clickhouse_helpers.py` around lines 398 - 414, The
two new ClickHouse URL parsing tests are currently defined at module scope, but
the rest of the related URL kwargs tests live inside TestClickHouseUrlKwargs.
Move the new bracketed-password cases into the TestClickHouseUrlKwargs class and
keep using _FakeConnInfoFromUrl and _build_clickhouse_client_kwargs so the test
grouping and reporting stay consistent with the existing suite.
core/wren/src/wren/connector/clickhouse.py (1)

248-278: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Consider extracting bracket sanitization into a shared utility.

The docstring notes this "Mirrors the MySQL connector helper," indicating the same userinfo-bracket-escaping logic exists in MySQL, MSSQL, and Oracle connectors. Extracting this into a shared helper (e.g., wren.connector._url_utils.sanitize_userinfo_brackets) would eliminate duplication and ensure fixes propagate to all connectors automatically.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/wren/src/wren/connector/clickhouse.py` around lines 248 - 278, The
ClickHouse URL parser currently duplicates the userinfo bracket-escaping logic
already used by other connectors, so extract that behavior into a shared URL
helper and reuse it here. Move the sanitization from
_parse_clickhouse_connection_url into a common utility such as
sanitize_userinfo_brackets in a shared module, then call that helper from
ClickHouse and the other connector parsers that mirror this behavior. Keep the
existing parsing flow in _parse_clickhouse_connection_url intact, but replace
the inline replace logic with the shared helper so future fixes apply
consistently across all connectors.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@core/wren/src/wren/connector/clickhouse.py`:
- Around line 248-278: The ClickHouse URL parser currently duplicates the
userinfo bracket-escaping logic already used by other connectors, so extract
that behavior into a shared URL helper and reuse it here. Move the sanitization
from _parse_clickhouse_connection_url into a common utility such as
sanitize_userinfo_brackets in a shared module, then call that helper from
ClickHouse and the other connector parsers that mirror this behavior. Keep the
existing parsing flow in _parse_clickhouse_connection_url intact, but replace
the inline replace logic with the shared helper so future fixes apply
consistently across all connectors.

In `@core/wren/tests/unit/test_clickhouse_helpers.py`:
- Around line 398-414: The two new ClickHouse URL parsing tests are currently
defined at module scope, but the rest of the related URL kwargs tests live
inside TestClickHouseUrlKwargs. Move the new bracketed-password cases into the
TestClickHouseUrlKwargs class and keep using _FakeConnInfoFromUrl and
_build_clickhouse_client_kwargs so the test grouping and reporting stay
consistent with the existing suite.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 57415b41-a808-4224-b2da-3f4e3094adfc

📥 Commits

Reviewing files that changed from the base of the PR and between c4de8ac and 8db4a3e.

📒 Files selected for processing (2)
  • core/wren/src/wren/connector/clickhouse.py
  • core/wren/tests/unit/test_clickhouse_helpers.py

@goldmedal goldmedal left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks @Bartok9 👍

@goldmedal
goldmedal merged commit ef0a824 into Canner:main Jul 13, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core python Pull requests that update Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants