Skip to content

Validate port range in URL.build#1769

Open
HrachShah wants to merge 2 commits into
aio-libs:masterfrom
HrachShah:fix/build-port-range-validate
Open

Validate port range in URL.build#1769
HrachShah wants to merge 2 commits into
aio-libs:masterfrom
HrachShah:fix/build-port-range-validate

Conversation

@HrachShah

Copy link
Copy Markdown

What do these changes do?

URL.build now rejects ports outside 0..65535 at the call site, matching the check that already exists in URL.with_port. Previously the constructor accepted any integer, formatted it into the netloc, and the failure surfaced only later inside split_netloc when something forced a netloc cache rebuild (str(url), accessing host_subcomponent, etc.). The authority=... path was unaffected because it goes through split_netloc up front and raised immediately.

The fix is two lines in URL.build that mirror the wording of with_port, plus parametrized regression tests covering both encoded=False and encoded=True, with three out-of-range inputs (65536, 99999, -1).

Are there changes in behavior for the user?

Yes. URL.build(scheme="http", host="example.com", port=65536) now raises ValueError: port must be between 0 and 65535, got 65536 at the call site rather than waiting until the URL is rendered or one of its properties is accessed. The error message and shape match URL.with_port. Inputs in the existing range (including 0) behave identically.

Is it a substantial burden for the maintainers to support this?

No. It is one new guard plus a regression test and a CHANGES fragment; the public surface (URL.build's signature and the error type) is unchanged.

Related issue number

None.

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes
  • Add a new news fragment into the CHANGES/ folder
Agent run details (optional, for reviewers)

Tests: PYTHONPATH=. python3 -m pytest tests -p no:cacheprovider --override-ini="addopts=" -> 1462 passed, 101 skipped (benchmarks), 4 xfailed.

The tests/test_quoting.py collection error reproduces on a clean checkout without the Cython extension built (it imports yarl._quoting_c); running CC=gcc pip install -e . first builds the extension in place and the suite goes green. The 9 doc-spelling warnings come from the existing CHANGES.rst history and unrelated towncrier fragments, not from 1769.bugfix.rst.

Drafted with Zo (MiniMax M3); reviewed by HrachShah.

URL.build accepted ports outside the 0..65535 range and stored them
as-is. The error surfaced later, when _cache_netloc() ran split_netloc()
on the rendered netloc and raised ValueError('Port out of range 0-65535')
deep inside that helper rather than from the caller's frame. URL.with_port
already had the equivalent range check; align URL.build with it so the
failure happens eagerly and with a message that names the argument.

The encoded=True branch went through build_pre_encoded_url, which
calls make_netloc() and formats the port with f'{host}:{port}' without
any range check. The same eager check in URL.build now catches it too.

Add 8 regression cases across test_build_with_port, test_build_with_out_of_range_port
and test_build_with_out_of_range_port_encoded covering 65536, 99999 and -1 in
both encoded and non-encoded paths; all 8 fail on master before the fix.
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided There is a change note present in this PR label Jun 26, 2026
@codspeed-hq

codspeed-hq Bot commented Jun 26, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 97 untouched benchmarks


Comparing HrachShah:fix/build-port-range-validate (fa84ec8) with master (315a7aa)1

Open in CodSpeed

Footnotes

  1. No successful run was found on master (b0d27e4) during the generation of this report, so 315a7aa was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.86%. Comparing base (b0d27e4) to head (fa84ec8).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1769   +/-   ##
=======================================
  Coverage   99.86%   99.86%           
=======================================
  Files          21       21           
  Lines        4310     4320   +10     
  Branches      252      253    +1     
=======================================
+ Hits         4304     4314   +10     
  Misses          4        4           
  Partials        2        2           
Flag Coverage Δ
CI-GHA 99.79% <100.00%> (+<0.01%) ⬆️
OS-Linux 99.79% <100.00%> (+<0.01%) ⬆️
OS-Windows 98.54% <100.00%> (+<0.01%) ⬆️
OS-macOS 98.72% <100.00%> (+<0.01%) ⬆️
Py-3.10 99.69% <100.00%> (+<0.01%) ⬆️
Py-3.11 99.69% <100.00%> (+<0.01%) ⬆️
Py-3.12 99.69% <100.00%> (+<0.01%) ⬆️
Py-3.13 99.74% <100.00%> (+<0.01%) ⬆️
Py-3.14 99.74% <100.00%> (+<0.01%) ⬆️
Py-3.14t 99.74% <100.00%> (+<0.01%) ⬆️
Py-pypy-3.11 99.37% <100.00%> (+<0.01%) ⬆️
VM-macos-latest 98.72% <100.00%> (+<0.01%) ⬆️
VM-ubuntu-latest 99.79% <100.00%> (+<0.01%) ⬆️
VM-windows-latest 98.54% <100.00%> (+<0.01%) ⬆️
pytest 99.79% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 28216354684

Coverage increased (+0.006%) to 98.746%

Details

  • Coverage increased (+0.006%) from the base build.
  • Patch coverage: 30 of 30 lines across 2 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 6239
Covered Lines: 6160
Line Coverage: 98.73%
Relevant Branches: 61
Covered Branches: 61
Branch Coverage: 100.0%
Branches in Coverage %: Yes
Coverage Strength: 0.99 hits per line

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided There is a change note present in this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants