Skip to content

An out-of-range -P proxy port parses to a garbage port instead of being rejected#610

Merged
xroche merged 2 commits into
masterfrom
fix-602-proxy-port
Jul 17, 2026
Merged

An out-of-range -P proxy port parses to a garbage port instead of being rejected#610
xroche merged 2 commits into
masterfrom
fix-602-proxy-port

Conversation

@xroche

@xroche xroche commented Jul 16, 2026

Copy link
Copy Markdown
Owner

hts_parse_proxy read the proxy port with sscanf(a, "%d", &p). A value that doesn't fit an int is undefined behavior there (C11 7.21.6.2p10), and glibc wraps instead of failing, so -P 'http://host:99999999999999' connected to port 276447231 while -P 'http://host:4294967296' happened to fail and fall back to the default. 65536 was taken at face value. The port now goes through strtol with a 1..65535 range check, so anything out of range or malformed falls back to proxy_default_port, exactly as an unparsable port already did. RFC 3986 allows any digit string; the 1..65535 bound is TCP's 16-bit port field.

Two smaller behavior changes come with it, both reachable only from a malformed -P. A port with trailing garbage is now rejected, so -P 'host:80x' defaults instead of silently connecting to 80. A leading + or space is rejected too. A leading - already was.

The self-test covers the range fence and the overflow values from the issue, plus 4294967376. That one wraps to a plausible port 80, so it catches a fix that range-checks the sscanf result instead of rejecting the overflow. Six of the fourteen cases discriminate against a buggy build: the fence on both sides, trailing garbage, leading space, the socks5 default, and 4294967376. The rest already pass on master and pin the behavior.

Closes #602

xroche and others added 2 commits July 16, 2026 18:58
hts_parse_proxy read the port with sscanf(a, "%d", &p), which is signed
overflow UB past INT_MAX. glibc wraps rather than fails, so a garbage
port got through: -P 'http://host:99999999999999' parsed to port
276447231, while 'http://host:4294967296' happened to fail and fall back
to the default. 65536 was accepted as-is.

Parse with strtol and range-check to *DIGIT in 1..65535 (RFC 3986); an
out-of-range or malformed port now falls back to proxy_default_port,
exactly as an unparsable one already did.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
RFC 3986 defines port as *DIGIT with no range; the 1..65535 bound comes from
TCP's 16-bit port field.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
@xroche
xroche merged commit 959deb0 into master Jul 17, 2026
21 checks passed
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.

An out-of-range -P proxy port parses to a garbage port instead of being rejected

1 participant