From 7e80ab274efa8f3c751216d671d27b2d56d98117 Mon Sep 17 00:00:00 2001 From: Yarchik Date: Tue, 23 Jun 2026 17:04:42 +0100 Subject: [PATCH] fix(pg-connection-string): strip brackets from IPv6 host 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. --- packages/pg-connection-string/index.js | 5 ++++- packages/pg-connection-string/test/parse.ts | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/pg-connection-string/index.js b/packages/pg-connection-string/index.js index 7ee302976..56423d124 100644 --- a/packages/pg-connection-string/index.js +++ b/packages/pg-connection-string/index.js @@ -50,7 +50,10 @@ function parse(str, options = {}) { config.client_encoding = result.searchParams.get('encoding') return config } - const hostname = dummyHost ? '' : result.hostname + // The WHATWG URL parser keeps the square brackets around an IPv6 literal + // (e.g. [::1]); strip them so config.host is a bare address that libpq, and + // node's net.connect / dns.lookup, can use directly. + const hostname = (dummyHost ? '' : result.hostname).replace(/^\[(.+)\]$/, '$1') if (!config.host) { // Only set the host if there is no equivalent query param. config.host = decodeURIComponent(hostname) diff --git a/packages/pg-connection-string/test/parse.ts b/packages/pg-connection-string/test/parse.ts index c2a537581..59d8ef77c 100644 --- a/packages/pg-connection-string/test/parse.ts +++ b/packages/pg-connection-string/test/parse.ts @@ -111,6 +111,13 @@ describe('parse', function () { subject.host?.should.equal('localhost') }) + it('strips the brackets from an IPv6 host', function () { + const subject = parse('postgres://user:pw@[2001:db8::1]:5432/mydb') + subject.host?.should.equal('2001:db8::1') + subject.port?.should.equal('5432') + parse('postgres://[::1]/db').host?.should.equal('::1') + }) + it('url is properly encoded', function () { const encoded = 'pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl' const subject = parse(encoded)