diff --git a/lib/internal/util.js b/lib/internal/util.js index e690d7f4323bcc..7a928adb71c043 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -8,6 +8,7 @@ const { Error, ErrorCaptureStackTrace, FunctionPrototypeCall, + NumberParseInt, ObjectDefineProperties, ObjectDefineProperty, ObjectFreeze, @@ -33,7 +34,9 @@ const { SafeSet, SafeWeakMap, SafeWeakRef, + StringPrototypeIncludes, StringPrototypeReplace, + StringPrototypeSlice, StringPrototypeToLowerCase, StringPrototypeToUpperCase, Symbol, @@ -795,6 +798,59 @@ function setupCoverageHooks(dir) { return coverageDirectory; } +// Returns the number of ones in the binary representation of the decimal +// number. +function countBinaryOnes(n) { + // Count the number of bits set in parallel, which is faster than looping + n = n - ((n >>> 1) & 0x55555555); + n = (n & 0x33333333) + ((n >>> 2) & 0x33333333); + return ((n + (n >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; +} + +function getCIDR(address, netmask, family) { + let ones = 0; + let split = '.'; + let range = 10; + let groupLength = 8; + let hasZeros = false; + let lastPos = 0; + + if (family === 'IPv6') { + split = ':'; + range = 16; + groupLength = 16; + } + + for (let i = 0; i < netmask.length; i++) { + if (netmask[i] !== split) { + if (i + 1 < netmask.length) { + continue; + } + i++; + } + const part = StringPrototypeSlice(netmask, lastPos, i); + lastPos = i + 1; + if (part !== '') { + if (hasZeros) { + if (part !== '0') { + return null; + } + } else { + const binary = NumberParseInt(part, range); + const binaryOnes = countBinaryOnes(binary); + ones += binaryOnes; + if (binaryOnes !== groupLength) { + if (StringPrototypeIncludes(binary.toString(2), '01')) { + return null; + } + hasZeros = true; + } + } + } + } + + return `${address}/${ones}`; +} const handleTypes = ['TCP', 'TTY', 'UDP', 'FILE', 'PIPE', 'UNKNOWN']; function guessHandleType(fd) { @@ -861,6 +917,7 @@ module.exports = { filterDuplicateStrings, filterOwnProperties, getConstructorOf, + getCIDR, getCWDURL, getInternalGlobal, getStructuredStack, diff --git a/lib/os.js b/lib/os.js index 4f8dda1531b5dc..c44147f0e1170d 100644 --- a/lib/os.js +++ b/lib/os.js @@ -24,7 +24,6 @@ const { ArrayPrototypePush, Float64Array, - NumberParseInt, ObjectDefineProperties, StringPrototypeSlice, SymbolToPrimitive, @@ -40,6 +39,7 @@ const { }, hideStackFrames, } = require('internal/errors'); +const { getCIDR } = require('internal/util'); const { validateInt32 } = require('internal/validators'); const { @@ -202,60 +202,6 @@ function endianness() { } endianness[SymbolToPrimitive] = () => kEndianness; -// Returns the number of ones in the binary representation of the decimal -// number. -function countBinaryOnes(n) { - // Count the number of bits set in parallel, which is faster than looping - n = n - ((n >>> 1) & 0x55555555); - n = (n & 0x33333333) + ((n >>> 2) & 0x33333333); - return ((n + (n >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; -} - -function getCIDR(address, netmask, family) { - let ones = 0; - let split = '.'; - let range = 10; - let groupLength = 8; - let hasZeros = false; - let lastPos = 0; - - if (family === 'IPv6') { - split = ':'; - range = 16; - groupLength = 16; - } - - for (let i = 0; i < netmask.length; i++) { - if (netmask[i] !== split) { - if (i + 1 < netmask.length) { - continue; - } - i++; - } - const part = StringPrototypeSlice(netmask, lastPos, i); - lastPos = i + 1; - if (part !== '') { - if (hasZeros) { - if (part !== '0') { - return null; - } - } else { - const binary = NumberParseInt(part, range); - const binaryOnes = countBinaryOnes(binary); - ones += binaryOnes; - if (binaryOnes !== groupLength) { - if ((binary & 1) !== 0) { - return null; - } - hasZeros = true; - } - } - } - } - - return `${address}/${ones}`; -} - /** * @returns {Record