GeezerVison is showing github.com — os: fix netmask format check condition in getCIDR function · nodejs/node@8cd9822
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/util.js +57Lines changed: 57 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 8 | 8 | Error, | 9 | 9 | ErrorCaptureStackTrace, | 10 | 10 | FunctionPrototypeCall, | | 11 | + NumberParseInt, | 11 | 12 | ObjectDefineProperties, | 12 | 13 | ObjectDefineProperty, | 13 | 14 | ObjectFreeze, | @@ -33,7 +34,9 @@ const { | 33 | 34 | SafeSet, | 34 | 35 | SafeWeakMap, | 35 | 36 | SafeWeakRef, | | 37 | + StringPrototypeIncludes, | 36 | 38 | StringPrototypeReplace, | | 39 | + StringPrototypeSlice, | 37 | 40 | StringPrototypeToLowerCase, | 38 | 41 | StringPrototypeToUpperCase, | 39 | 42 | Symbol, | @@ -806,6 +809,59 @@ function setupCoverageHooks(dir) { | 806 | 809 | return coverageDirectory; | 807 | 810 | } | 808 | 811 |
| | 812 | +// Returns the number of ones in the binary representation of the decimal | | 813 | +// number. | | 814 | +function countBinaryOnes(n) { | | 815 | + // Count the number of bits set in parallel, which is faster than looping | | 816 | + n = n - ((n >>> 1) & 0x55555555); | | 817 | + n = (n & 0x33333333) + ((n >>> 2) & 0x33333333); | | 818 | + return ((n + (n >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; | | 819 | +} | | 820 | + | | 821 | +function getCIDR(address, netmask, family) { | | 822 | + let ones = 0; | | 823 | + let split = '.'; | | 824 | + let range = 10; | | 825 | + let groupLength = 8; | | 826 | + let hasZeros = false; | | 827 | + let lastPos = 0; | | 828 | + | | 829 | + if (family === 'IPv6') { | | 830 | + split = ':'; | | 831 | + range = 16; | | 832 | + groupLength = 16; | | 833 | + } | | 834 | + | | 835 | + for (let i = 0; i < netmask.length; i++) { | | 836 | + if (netmask[i] !== split) { | | 837 | + if (i + 1 < netmask.length) { | | 838 | + continue; | | 839 | + } | | 840 | + i++; | | 841 | + } | | 842 | + const part = StringPrototypeSlice(netmask, lastPos, i); | | 843 | + lastPos = i + 1; | | 844 | + if (part !== '') { | | 845 | + if (hasZeros) { | | 846 | + if (part !== '0') { | | 847 | + return null; | | 848 | + } | | 849 | + } else { | | 850 | + const binary = NumberParseInt(part, range); | | 851 | + const binaryOnes = countBinaryOnes(binary); | | 852 | + ones += binaryOnes; | | 853 | + if (binaryOnes !== groupLength) { | | 854 | + if (StringPrototypeIncludes(binary.toString(2), '01')) { | | 855 | + return null; | | 856 | + } | | 857 | + hasZeros = true; | | 858 | + } | | 859 | + } | | 860 | + } | | 861 | + } | | 862 | + | | 863 | + return `${address}/${ones}`; | | 864 | +} | 809 | 865 |
| 810 | 866 | const handleTypes = ['TCP', 'TTY', 'UDP', 'FILE', 'PIPE', 'UNKNOWN']; | 811 | 867 | function guessHandleType(fd) { | @@ -872,6 +928,7 @@ module.exports = { | 872 | 928 | filterDuplicateStrings, | 873 | 929 | filterOwnProperties, | 874 | 930 | getConstructorOf, | | 931 | + getCIDR, | 875 | 932 | getCWDURL, | 876 | 933 | getInternalGlobal, | 877 | 934 | getStructuredStack, | |
Collapse file Copy file name to clipboardExpand all lines: lib/os.js +1-55Lines changed: 1 addition & 55 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 24 | 24 | const { | 25 | 25 | ArrayPrototypePush, | 26 | 26 | Float64Array, | 27 | | - NumberParseInt, | 28 | 27 | ObjectDefineProperties, | 29 | 28 | StringPrototypeSlice, | 30 | 29 | SymbolToPrimitive, | @@ -40,6 +39,7 @@ const { | 40 | 39 | }, | 41 | 40 | hideStackFrames, | 42 | 41 | } = require('internal/errors'); | | 42 | +const { getCIDR } = require('internal/util'); | 43 | 43 | const { validateInt32 } = require('internal/validators'); | 44 | 44 |
| 45 | 45 | const { | @@ -202,60 +202,6 @@ function endianness() { | 202 | 202 | } | 203 | 203 | endianness[SymbolToPrimitive] = () => kEndianness; | 204 | 204 |
| 205 | | -// Returns the number of ones in the binary representation of the decimal | 206 | | -// number. | 207 | | -function countBinaryOnes(n) { | 208 | | - // Count the number of bits set in parallel, which is faster than looping | 209 | | - n = n - ((n >>> 1) & 0x55555555); | 210 | | - n = (n & 0x33333333) + ((n >>> 2) & 0x33333333); | 211 | | - return ((n + (n >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; | 212 | | -} | 213 | | - | 214 | | -function getCIDR(address, netmask, family) { | 215 | | - let ones = 0; | 216 | | - let split = '.'; | 217 | | - let range = 10; | 218 | | - let groupLength = 8; | 219 | | - let hasZeros = false; | 220 | | - let lastPos = 0; | 221 | | - | 222 | | - if (family === 'IPv6') { | 223 | | - split = ':'; | 224 | | - range = 16; | 225 | | - groupLength = 16; | 226 | | - } | 227 | | - | 228 | | - for (let i = 0; i < netmask.length; i++) { | 229 | | - if (netmask[i] !== split) { | 230 | | - if (i + 1 < netmask.length) { | 231 | | - continue; | 232 | | - } | 233 | | - i++; | 234 | | - } | 235 | | - const part = StringPrototypeSlice(netmask, lastPos, i); | 236 | | - lastPos = i + 1; | 237 | | - if (part !== '') { | 238 | | - if (hasZeros) { | 239 | | - if (part !== '0') { | 240 | | - return null; | 241 | | - } | 242 | | - } else { | 243 | | - const binary = NumberParseInt(part, range); | 244 | | - const binaryOnes = countBinaryOnes(binary); | 245 | | - ones += binaryOnes; | 246 | | - if (binaryOnes !== groupLength) { | 247 | | - if ((binary & 1) !== 0) { | 248 | | - return null; | 249 | | - } | 250 | | - hasZeros = true; | 251 | | - } | 252 | | - } | 253 | | - } | 254 | | - } | 255 | | - | 256 | | - return `${address}/${ones}`; | 257 | | -} | 258 | | - | 259 | 205 | /** | 260 | 206 | * @returns {Record<string, Array<{ | 261 | 207 | * address: string, | |
Collapse file Copy file name to clipboard +23Lines changed: 23 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// Flags: --expose-internals | | 2 | +'use strict'; | | 3 | +require('../common'); | | 4 | + | | 5 | +// These are tests that verify that the subnetmask is used | | 6 | +// to create the correct CIDR address. | | 7 | +// Tests that it returns null if the subnetmask is not in the correct format. | | 8 | +// (ref: https://www.rfc-editor.org/rfc/rfc1878) | | 9 | + | | 10 | +const assert = require('node:assert'); | | 11 | +const { getCIDR } = require('internal/util'); | | 12 | + | | 13 | +assert.strictEqual(getCIDR('127.0.0.1', '255.0.0.0', 'IPv4'), '127.0.0.1/8'); | | 14 | +assert.strictEqual(getCIDR('127.0.0.1', '255.255.0.0', 'IPv4'), '127.0.0.1/16'); | | 15 | + | | 16 | +// 242 = 11110010(2) | | 17 | +assert.strictEqual(getCIDR('127.0.0.1', '242.0.0.0', 'IPv4'), null); | | 18 | + | | 19 | +assert.strictEqual(getCIDR('::1', 'ffff:ffff:ffff:ffff::', 'IPv6'), '::1/64'); | | 20 | +assert.strictEqual(getCIDR('::1', 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', 'IPv6'), '::1/128'); | | 21 | + | | 22 | +// ff00:ffff = 11111111 00000000 : 11111111 11111111(2) | | 23 | +assert.strictEqual(getCIDR('::1', 'ffff:ff00:ffff::', 'IPv6'), null); |
|