mirror of
https://github.com/jason5ng32/MyIP.git
synced 2026-11-04 08:55:47 +00:00
Fix(ip): validate subnet split limits before conversion
Return null for invalid options or limits instead of throwing during BigInt conversion. Preserve zero, default, and safe integer limits. Co-Authored-By: GPT-6 <noreply@openai.com>
This commit is contained in:
1 parent
6de54d7e44
commit
0c6e5f2c7a
2 files changed
+27
-1
No files matched your search
+4
-1
@@ -281,7 +281,10 @@ export const compareIps = (a, b) => {
|
||||
|
||||
// Children of `cidrStr` at `newPrefix`. `total` is exact; `subnets` stops at
|
||||
// `limit` so a /8 → /32 request never materialises 16M strings.
|
||||
export const splitCidr = (cidrStr, newPrefix, { limit = 1024 } = {}) => {
|
||||
export const splitCidr = (cidrStr, newPrefix, options = {}) => {
|
||||
if (!options || typeof options !== 'object' || Array.isArray(options)) return null;
|
||||
const { limit = 1024 } = options;
|
||||
if (!Number.isSafeInteger(limit) || limit < 0) return null;
|
||||
const cidr = parseCidr(cidrStr);
|
||||
if (!cidr || !isPrefix(newPrefix, cidr.family) || newPrefix < cidr.prefix) return null;
|
||||
const { family, network } = cidr;
|
||||
|
||||
@@ -293,6 +293,29 @@ describe('containment & ordering', () => {
|
||||
});
|
||||
|
||||
describe('splitCidr', () => {
|
||||
it('rejects invalid limits and options without coercing them', () => {
|
||||
const limits = [Infinity, -Infinity, NaN, 1.5, -1, Number.MAX_SAFE_INTEGER + 1,
|
||||
Symbol('limit'), '4', 4n, null, true, {}, []];
|
||||
for (const limit of limits) {
|
||||
assert.equal(splitCidr('10.0.0.0/24', 26, { limit }), null);
|
||||
assert.equal(splitCidr('2001:db8::/32', 48, { limit }), null);
|
||||
}
|
||||
for (const options of [null, false, 5, '4', 4n, Symbol('options'), []]) {
|
||||
assert.equal(splitCidr('10.0.0.0/24', 26, options), null);
|
||||
}
|
||||
});
|
||||
it('accepts zero, default and large safe limits without changing the exact total', () => {
|
||||
const zero = splitCidr('10.0.0.0/24', 26, { limit: 0 });
|
||||
assert.deepEqual(zero.subnets, []);
|
||||
assert.equal(zero.total, 4n);
|
||||
assert.equal(zero.truncated, true);
|
||||
for (const limit of [undefined, 4, Number.MAX_SAFE_INTEGER]) {
|
||||
const result = splitCidr('10.0.0.0/24', 26, { limit });
|
||||
assert.equal(result.subnets.length, 4);
|
||||
assert.equal(result.total, 4n);
|
||||
assert.equal(result.truncated, false);
|
||||
}
|
||||
});
|
||||
it('splits a /24 into /26s', () => {
|
||||
const r = splitCidr('10.0.0.0/24', 26);
|
||||
assert.deepEqual(r.subnets, ['10.0.0.0/26', '10.0.0.64/26', '10.0.0.128/26', '10.0.0.192/26']);
|
||||
|
||||
Reference in new issue
Block a user