Fix(ip): reject out-of-family prefix containment values

Validate both network and address against the selected IP family.
Cover negative values, overflow, and valid IPv4 and IPv6 boundaries.

Co-Authored-By: GPT-6 <noreply@openai.com>
This commit is contained in:
jason5ng32andGPT-6 committed 2026-09-17 10:49:17 +08:00
1 parent 1ec87945ce
commit 6de54d7e44
2 files changed
+19 -1

No files matched your search

+2 -1
View File
@@ -247,7 +247,8 @@ export const cidrInfo = (str) => {
/* ------------------------------------------------------------------ */
export const prefixContains = (network, prefix, family, value) => {
if (!isFamily(family) || !isPrefix(prefix, family) || !isBig(network) || !isBig(value)) return false;
if (!isFamily(family) || !isPrefix(prefix, family)
|| !inFamily(network, family) || !inFamily(value, family)) return false;
const shift = BigInt(BITS[family] - prefix);
return (value >> shift) === (network >> shift);
};
+17
View File
@@ -260,6 +260,23 @@ describe('containment & ordering', () => {
assert.equal(prefixContains(v4('10.0.0.0'), 8, 4, 5), false);
assert.equal(prefixContains(v4('10.0.0.0'), 33, 4, v4('10.1.2.3')), false);
});
it('prefixContains rejects negative and overflowing addresses in either position', () => {
for (const [family, bits] of [[4, 32], [6, 128]]) {
const overflow = 1n << BigInt(bits);
const max = overflow - 1n;
assert.equal(prefixContains(0n, 0, family, max), true);
assert.equal(prefixContains(max, bits, family, max), true);
for (const prefix of [0, 1, bits]) {
for (const invalid of [-1n, overflow, overflow + 1n]) {
assert.equal(prefixContains(invalid, prefix, family, invalid), false);
assert.equal(prefixContains(invalid, prefix, family, 0n), false);
assert.equal(prefixContains(0n, prefix, family, invalid), false);
}
}
assert.equal(prefixContains(-1n, 0, family, -2n), false);
assert.equal(prefixContains(overflow, 0, family, overflow + 1n), false);
}
});
it('cidrOverlaps', () => {
assert.equal(cidrOverlaps('10.0.0.0/8', '10.1.0.0/16'), true);
assert.equal(cidrOverlaps('10.1.0.0/16', '10.0.0.0/8'), true);