cidr-tools 12.1.0 → 12.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +60 -53
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -80,7 +80,7 @@ function doNormalize(cidr, opts) {
80
80
  const slashIndex = rangeSlashIndex;
81
81
  const prefixPresent = slashIndex !== -1;
82
82
  let prefixNum = prefixPresent ? parsePrefixNum(cidr, slashIndex) : -1;
83
- const { number, version } = parseIp(prefixPresent ? cidr.substring(0, slashIndex) : cidr);
83
+ const { number, version, ipv4mapped, scopeid } = parseIp(prefixPresent ? cidr.substring(0, slashIndex) : cidr);
84
84
  if (prefixNum === -1) prefixNum = bits[version];
85
85
  if (version === 4) {
86
86
  const hostBits = 32 - prefixNum;
@@ -96,10 +96,13 @@ function doNormalize(cidr, opts) {
96
96
  compress,
97
97
  hexify
98
98
  });
99
+ const start = hostBits > 0 ? number & hostNotMasks[hostBits] : number;
99
100
  const ip = stringifyIp({
100
- number: hostBits > 0 ? number & hostNotMasks[hostBits] : number,
101
- version
102
- });
101
+ number: start,
102
+ version,
103
+ ipv4mapped: ipv4mapped && start >> 32n === 65535n,
104
+ scopeid
105
+ }, { hexify });
103
106
  return (compress ? ip : normalizeIp(ip, {
104
107
  compress,
105
108
  hexify
@@ -241,17 +244,19 @@ function subparts4(pStart, pEnd, output) {
241
244
  }
242
245
  }
243
246
  function subparts6(pStart, pEnd, output) {
247
+ const fullSize = pEnd - pStart + 1n;
248
+ const startLowBit = pStart & -pStart;
249
+ if ((fullSize & fullSize - 1n) === 0n && (startLowBit === 0n || startLowBit >= fullSize)) {
250
+ output.push(stringifyIp({
251
+ number: pStart,
252
+ version: 6
253
+ }) + prefixStrings[129 - bigintBitLength(fullSize)]);
254
+ return;
255
+ }
244
256
  let start = pStart;
245
257
  while (start <= pEnd) {
246
258
  const size = pEnd - start + 1n;
247
259
  const lowBit = start & -start;
248
- if ((size & size - 1n) === 0n && (lowBit === 0n || lowBit >= size)) {
249
- output.push(stringifyIp({
250
- number: start,
251
- version: 6
252
- }) + prefixStrings[129 - bigintBitLength(size)]);
253
- return;
254
- }
255
260
  const blockSize = lowBit !== 0n && lowBit <= size ? lowBit : biggestPowerOfTwo(size);
256
261
  output.push(stringifyIp({
257
262
  number: start,
@@ -547,60 +552,62 @@ function containsCidr(a, b) {
547
552
  }
548
553
  if (v4b.length > 0) {
549
554
  if (v4a.length === 0) return false;
550
- if (v4b.length === 1) {
551
- const ts = v4b[0].start, te = v4b[0].end;
552
- let found = false;
553
- for (const a of v4a) if (a.start <= ts && a.end >= te) {
554
- found = true;
555
+ let sorted = false;
556
+ for (const target of v4b) {
557
+ const ts = target.start, te = target.end;
558
+ let covered = false;
559
+ for (const iv of v4a) {
560
+ if (iv.start > ts || iv.end < te) continue;
561
+ covered = true;
555
562
  break;
556
563
  }
557
- if (!found) return false;
558
- } else {
559
- v4a.sort(cmpV4Start);
560
- const maxEnd = new Array(v4a.length);
561
- maxEnd[0] = v4a[0].end;
562
- for (let i = 1; i < v4a.length; i++) maxEnd[i] = Math.max(v4a[i].end, maxEnd[i - 1]);
563
- for (const target of v4b) {
564
- let lo = 0, hi = v4a.length - 1;
565
- let idx = -1;
566
- while (lo <= hi) {
567
- const mid = lo + hi >> 1;
568
- if (v4a[mid].start <= target.start) {
569
- idx = mid;
570
- lo = mid + 1;
571
- } else hi = mid - 1;
564
+ if (covered) continue;
565
+ if (!sorted) {
566
+ v4a.sort(cmpV4Start);
567
+ sorted = true;
568
+ }
569
+ let cur = ts;
570
+ for (const iv of v4a) {
571
+ if (iv.start > cur) break;
572
+ if (iv.end >= cur) {
573
+ if (iv.end >= te) {
574
+ covered = true;
575
+ break;
576
+ }
577
+ cur = iv.end + 1;
572
578
  }
573
- if (idx < 0 || maxEnd[idx] < target.end) return false;
574
579
  }
580
+ if (!covered) return false;
575
581
  }
576
582
  }
577
583
  if (v6b.length > 0) {
578
584
  if (v6a.length === 0) return false;
579
- if (v6b.length === 1) {
580
- const ts = v6b[0].start, te = v6b[0].end;
581
- let found = false;
582
- for (const a of v6a) if (a.start <= ts && a.end >= te) {
583
- found = true;
585
+ let sorted = false;
586
+ for (const target of v6b) {
587
+ const ts = target.start, te = target.end;
588
+ let covered = false;
589
+ for (const iv of v6a) {
590
+ if (iv.start > ts || iv.end < te) continue;
591
+ covered = true;
584
592
  break;
585
593
  }
586
- if (!found) return false;
587
- } else {
588
- v6a.sort(cmpV6Start);
589
- const maxEnd = new Array(v6a.length);
590
- maxEnd[0] = v6a[0].end;
591
- for (let i = 1; i < v6a.length; i++) maxEnd[i] = v6a[i].end > maxEnd[i - 1] ? v6a[i].end : maxEnd[i - 1];
592
- for (const target of v6b) {
593
- let lo = 0, hi = v6a.length - 1;
594
- let idx = -1;
595
- while (lo <= hi) {
596
- const mid = lo + hi >> 1;
597
- if (v6a[mid].start <= target.start) {
598
- idx = mid;
599
- lo = mid + 1;
600
- } else hi = mid - 1;
594
+ if (covered) continue;
595
+ if (!sorted) {
596
+ v6a.sort(cmpV6Start);
597
+ sorted = true;
598
+ }
599
+ let cur = ts;
600
+ for (const iv of v6a) {
601
+ if (iv.start > cur) break;
602
+ if (iv.end >= cur) {
603
+ if (iv.end >= te) {
604
+ covered = true;
605
+ break;
606
+ }
607
+ cur = iv.end + 1n;
601
608
  }
602
- if (idx < 0 || maxEnd[idx] < target.end) return false;
603
609
  }
610
+ if (!covered) return false;
604
611
  }
605
612
  }
606
613
  return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cidr-tools",
3
- "version": "12.1.0",
3
+ "version": "12.1.2",
4
4
  "author": "silverwind <me@silverwind.io>",
5
5
  "description": "Tools to work with IPv4 and IPv6 CIDR",
6
6
  "keywords": [
@@ -32,14 +32,14 @@
32
32
  "ip-bigint": "^9.0.6"
33
33
  },
34
34
  "devDependencies": {
35
- "@types/node": "25.9.3",
36
- "@typescript/native-preview": "7.0.0-dev.20260616.1",
35
+ "@types/node": "26.0.1",
36
+ "@typescript/native-preview": "7.0.0-dev.20260627.2",
37
37
  "@vitest/coverage-v8": "4.1.9",
38
- "eslint": "10.5.0",
39
- "eslint-config-silverwind": "136.0.10",
38
+ "eslint": "10.6.0",
39
+ "eslint-config-silverwind": "138.0.0",
40
40
  "jest-extended": "7.0.0",
41
41
  "tsdown": "0.22.3",
42
- "tsdown-config-silverwind": "3.0.3",
42
+ "tsdown-config-silverwind": "3.0.4",
43
43
  "typescript": "6.0.3",
44
44
  "typescript-config-silverwind": "20.0.0",
45
45
  "updates": "17.18.0",