Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions pkgs/development/web/nodejs/fix-libuv-1.53-support.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
Extracted from https://github.com/nodejs/node/pull/66282

diff --git a/src/node_sockaddr.cc b/src/node_sockaddr.cc
index 3f903f548e17..7c2285de32dd 100644
--- a/src/node_sockaddr.cc
+++ b/src/node_sockaddr.cc
@@ -1046,8 +1046,8 @@ bool SocketAddressBlockListWrap::FastCheckString(
// FastOneByteString is not NUL-terminated. Copy onto the stack
// before any other work: a GC would invalidate `address`.
//
- // uv_ip6_addr only needs the address part (≤39 chars) plus an
- // optional %zone. A zone longer than UV_IF_NAMESIZE is unknown
+ // uv_ip6_addr only needs the address part (< INET6_ADDRSTRLEN chars)
+ // plus an optional %zone. A zone longer than UV_IF_NAMESIZE is unknown
// (scope_id 0), same as omitting it. Keep that behavior when the
// full string does not fit so Fast API and CheckString agree.
constexpr size_t kMax = INET6_ADDRSTRLEN + UV_IF_NAMESIZE;
@@ -1058,14 +1058,14 @@ bool SocketAddressBlockListWrap::FastCheckString(
} else if (family == AF_INET6) {
// uv_ip4_addr rejects %zone. Only IPv6 may drop an overlong zone
// (unknown zone → scope_id 0, same as uv_ip6_addr).
- // uv_ip6_addr copies the address part into a 40-byte buffer
- // (39 chars + NUL). A 40+ char prefix (mixed notation) is
- // truncated and fails inet_pton — do not keep the full prefix.
+ // uv_ip6_addr copies the address part into an INET6_ADDRSTRLEN
+ // buffer and truncates a longer one to INET6_ADDRSTRLEN - 1 chars
+ // before inet_pton. Do the same so both paths parse the same prefix.
const char* percent =
static_cast<const char*>(memchr(address.data, '%', address.length));
if (percent == nullptr) return false;
- const size_t addr_len = static_cast<size_t>(percent - address.data);
- if (addr_len >= 40) return false;
+ size_t addr_len = static_cast<size_t>(percent - address.data);
+ if (addr_len >= INET6_ADDRSTRLEN) addr_len = INET6_ADDRSTRLEN - 1;
memcpy(buf, address.data, addr_len);
buf[addr_len] = '\0';
} else {
diff --git a/test/parallel/test-blocklist.js b/test/parallel/test-blocklist.js
index b0fe4303bfb2..c548917b1c77 100644
--- a/test/parallel/test-blocklist.js
+++ b/test/parallel/test-blocklist.js
@@ -883,12 +883,17 @@ const util = require('util');
blockList.addAddress('1.1.1.1');
assert.strictEqual(blockList.check(`1.1.1.1%${'z'.repeat(200)}`), false);

- // Mixed-notation IPv6 is 45 chars. uv_ip6_addr truncates the
- // address part to 39 when a zone is present, so this is a miss.
+ // Mixed-notation IPv6 is 45 chars. uv_ip6_addr keeps up to
+ // INET6_ADDRSTRLEN - 1 chars of the address part when a zone is
+ // present, so this is a hit on libuv 1.53+.
const mixed = 'ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255';
blockList.addAddress(mixed, 'ipv6');
assert.strictEqual(blockList.check(mixed, 'ipv6'), true);
- assert.strictEqual(blockList.check(`${mixed}%${'z'.repeat(200)}`, 'ipv6'), false);
+ const isModernLibuv = ((versionString) => {
+ const [major, minor] = versionString.split('.', 2).map(Number);
+ return major >= 1 && minor >= 53;
+ })(process.versions.uv);
+ assert.strictEqual(blockList.check(`${mixed}%${'z'.repeat(200)}`, 'ipv6'), isModernLibuv);
}

// check() family parameter is case-insensitive.
3 changes: 3 additions & 0 deletions pkgs/development/web/nodejs/v26.nix
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ buildNodejs {

# https://github.com/NixOS/nixpkgs/issues/568974
./memcpy-climits.patch

# TODO: remove once support for libuv 1.53+ has landed upstream
./fix-libuv-1.53-support.patch
]
++ gypPatches;
}
Loading