{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"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","sourcesContent":["import { Address4 } from './ipv4';\nimport { Address6 } from './ipv6';\nimport { AddressError } from './address-error';\n\nexport interface ReverseFormOptions {\n omitSuffix?: boolean;\n}\n\n/**\n * Returns whether this address's *network* is contained within `address`,\n * i.e. whether every address this one can represent also falls inside\n * `address`. A network wider than `address` is not contained in it, so\n * `10.0.0.0/8` is not in `10.0.0.0/16`.\n *\n * To ask whether the address itself falls inside a range, ignoring any CIDR\n * suffix it was written with, use {@link isHostInSubnet} instead. That is the\n * question the special-use classifiers ask.\n */\nexport function isInSubnet(this: Address4 | Address6, address: Address4 | Address6) {\n if (this.subnetMask < address.subnetMask) {\n return false;\n }\n\n return isHostInSubnet.call(this, address);\n}\n\n/**\n * Returns whether this address's host bits fall inside `address`, ignoring\n * this address's own subnet mask.\n *\n * This is the primitive the special-use classifiers (`isLoopback`,\n * `isPrivate`, `isLinkLocal`, `getType`, …) are built on: they answer a\n * question about the address, so the answer must not change with the CIDR\n * suffix the caller happened to write. Use this rather than\n * {@link isInSubnet} when classifying a single address — notably when the\n * address came from untrusted input and the result backs a trust-boundary\n * decision such as an SSRF allow/deny filter.\n *\n * An address of one family is never inside a network of the other, so an\n * `Address4` against an `Address6` (or the reverse) is `false`. To compare\n * across families, convert first: `Address6.fromAddress4()`, `to4()`, or\n * `toAddress4Nat64()`.\n */\nexport function isHostInSubnet(this: Address4 | Address6, address: Address4 | Address6) {\n // mask() is a bit string of the family's width, and the leading bits of a\n // 32-bit string can coincide with those of a 128-bit one (a00::1 and\n // 10.0.0.0/8 both mask to 00001010), so the widths must agree before the\n // strings are compared.\n if (this.binaryZeroPad().length !== address.binaryZeroPad().length) {\n return false;\n }\n\n return this.mask(address.subnetMask) === address.mask();\n}\n\n/**\n * One parsed row of an IANA special-purpose address registry: the block, and\n * whether the registry marks it globally reachable (`null` when the column is\n * blank, in which case the containing block answers).\n */\nexport interface SpecialPurposeEntry {\n subnet: A;\n reachable: boolean | null;\n}\n\n/**\n * Returns whether the registry marks this address globally reachable: the\n * answer of the most specific entry containing it that has one, or `true`\n * when no entry contains it.\n */\nexport function isGloballyReachable(\n this: A,\n entries: ReadonlyArray>,\n): boolean {\n let best: SpecialPurposeEntry | null = null;\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n\n if (\n entry.reachable !== null &&\n isHostInSubnet.call(this, entry.subnet) &&\n (best === null || entry.subnet.subnetMask > best.subnet.subnetMask)\n ) {\n best = entry;\n }\n }\n\n return best === null ? true : (best.reachable as boolean);\n}\n\n/**\n * Adds `n` to `value` and returns the result, throwing `AddressError` unless\n * `n` is an integer and the result stays within `[0, 2**bits - 1]`.\n */\nexport function offsetBigInt(\n value: bigint,\n n: number | bigint,\n bits: number,\n family: string,\n): bigint {\n if (typeof n === 'number' && !Number.isSafeInteger(n)) {\n throw new AddressError(`${family} offset must be an integer`);\n }\n\n if (typeof n !== 'number' && typeof n !== 'bigint') {\n throw new AddressError(`${family} offset must be an integer`);\n }\n\n const result = value + BigInt(n);\n\n if (result < BigInt(0) || result > (BigInt(1) << BigInt(bits)) - BigInt(1)) {\n throw new AddressError(`${family} offset leaves the address space`);\n }\n\n return result;\n}\n\nexport function isCorrect(defaultBits: number) {\n return function isCorrectForm(this: Address4 | Address6) {\n if (this.addressMinusSuffix !== this.correctForm()) {\n return false;\n }\n\n if (this.subnetMask === defaultBits && !this.parsedSubnet) {\n return true;\n }\n\n return this.parsedSubnet === String(this.subnetMask);\n };\n}\n\n/**\n * Returns the prefix length (number of leading 1 bits) of a contiguous\n * subnet mask. Throws `AddressError` if the mask is non-contiguous (e.g.\n * `255.0.255.0`).\n */\nexport function prefixLengthFromMask(value: bigint, totalBits: number): number {\n const binary = value.toString(2).padStart(totalBits, '0');\n\n if (binary.length > totalBits) {\n throw new AddressError('Invalid subnet mask.');\n }\n\n const firstZero = binary.indexOf('0');\n\n if (firstZero === -1) {\n return totalBits;\n }\n\n if (binary.slice(firstZero).includes('1')) {\n throw new AddressError('Invalid subnet mask.');\n }\n\n return firstZero;\n}\n\n/**\n * Throws `AddressError` unless `bytes` holds exactly `byteCount` integers,\n * each from `minimum` to 255. Pass a `minimum` of `-128` where signed bytes\n * are accepted and folded to unsigned, and `0` where they are not.\n */\nexport function assertByteArray(\n bytes: number[],\n byteCount: number,\n family: 'IPv4' | 'IPv6',\n minimum: number,\n): void {\n if (bytes.length !== byteCount) {\n throw new AddressError(`${family} addresses require exactly ${byteCount} bytes`);\n }\n\n for (let i = 0; i < bytes.length; i++) {\n if (!Number.isInteger(bytes[i]) || bytes[i] < minimum || bytes[i] > 255) {\n throw new AddressError(`All bytes must be integers between ${minimum} and 255`);\n }\n }\n}\n\nexport function numberToPaddedHex(number: number) {\n return number.toString(16).padStart(2, '0');\n}\n\nexport function stringToPaddedHex(numberString: string) {\n return numberToPaddedHex(parseInt(numberString, 10));\n}\n\n/**\n * @param binaryValue Binary representation of a value (e.g. `10`)\n * @param position Byte position, where 0 is the least significant bit\n */\nexport function testBit(binaryValue: string, position: number): boolean {\n const { length } = binaryValue;\n\n if (position > length) {\n return false;\n }\n\n const positionInString = length - position;\n return binaryValue.substring(positionInString, positionInString + 1) === '1';\n}\n"]}