fix(pg-connection-string): strip brackets from IPv6 host - #3698
Conversation
The WHATWG URL parser keeps the square brackets around an IPv6 literal,
so parse('postgresql://[::1]:5432/db').host returned '[::1]'. libpq
stores the address without the brackets, and consumers pass config.host
straight to net.connect / dns.lookup, which treat '[::1]' as a hostname
and fail with ENOTFOUND. Strip the brackets so IPv6 connection strings
resolve to the bare address.
|
Independent confirmation, in case a second data point helps this get looked at. Hit while pointing a local tool's
const { parse } = require('pg-connection-string')
parse('postgres://u@[::1]:5436/db').host // '[::1]'
parse('postgres://u@[2001:db8::1]:5432/db').host // '[2001:db8::1]'
parse('postgres://u@127.0.0.1:5436/db').host // '127.0.0.1' (unaffected)End-to-end through Same server, same port, only the brackets differ — which isolates it to the parse step rather than to IPv6 connectivity (the server here is Postgres in Docker published on For anyone arriving from a search: the workaround until this lands is |
|
thanks for looking into this - curious if this also impacts libpq / the native bindings? I don't want to break them w/ this change. I'd honestly prefer if this is causing an issue for people this is fixed either in dns.lookup or by removing the brackes in client code. One other option is stripping the |
Problem
pg-connection-stringleaves the URI square brackets on the host for IPv6 literals, so the parsedhostis unusable:The brackets are RFC 3986 / WHATWG URI delimiters for an IPv6 host, not part of the address. libpq stores the bracket-free literal, and
pgpassesconfig.hoststraight tonet.connect/dns.lookup:So every IPv6 connection string fails to connect today. There is no test or option covering IPv6, so this is an unguarded gap, not intentional.
Fix
Strip a leading
[/ trailing]from the parsed hostname:Unconditional
replace(no new branch, keeps 100% branch coverage); a no-op for non-bracketed hosts.Verification
postgres://user:pw@[2001:db8::1]:5432/mydb→ host2001:db8::1, port5432;[::1]→::1. Fails onmaster, passes with the fix.%2F...), the?host=query-param override, and a bracketed database name (%5Bweird%5Dstays[weird]).conninfo_uri_parse_options, which advances past[and NUL-terminates at](stores the bare literal).nyc check-coverage100% maintained.