mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2025-04-30 13:11:37 +03:00
Pull request 734: + client: 1778 Add ip sort function, write unit tests
Close #1778 Squashed commit of the following: commit ba63e147311799b17deaa97d7a12c2e0ec44a2ed Merge: 143ba427705a9d90
Author: ArtemBaskal <a.baskal@adguard.com> Date: Thu Aug 13 12:00:10 2020 +0300 Merge branch 'master' into feature/1778 commit 143ba42707da3d7eece9f3e137a8b245f7f7888f Merge: 483d2ff997df1989
Author: ArtemBaskal <a.baskal@adguard.com> Date: Thu Aug 13 11:16:46 2020 +0300 Merge branch 'master' into feature/1778 commit 483d2ff9fa3de706d94a647701f1d26a3bcbb217 Author: ArtemBaskal <a.baskal@adguard.com> Date: Wed Aug 12 13:34:21 2020 +0300 Always put ipv4 before ipv6 in sort, add invalid input unit tests commit 26eb41b313785fe7ffaf98a7573cc5eef0dca14f Author: ArtemBaskal <a.baskal@adguard.com> Date: Wed Aug 12 11:27:46 2020 +0300 Rewrite tests: replace ipv4-mapped adresses commit 4ecf287fd46945effe9ff11cfc9ae49217b9c796 Author: ArtemBaskal <a.baskal@adguard.com> Date: Tue Aug 11 19:05:15 2020 +0300 Minor fix commit 3e5e2a6bb1f2f166619da54e5ade0904fe22a20d Author: ArtemBaskal <a.baskal@adguard.com> Date: Tue Aug 11 19:01:26 2020 +0300 + client: 1778 Add ip sort function, write unit tests
This commit is contained in:
parent
705a9d909d
commit
2f8e34e73b
6 changed files with 427 additions and 4 deletions
client/src/helpers
|
@ -681,3 +681,68 @@ export const processContent = (content) => (Array.isArray(content)
|
|||
export const getObjectKeysSorted = (object, sortKey) => Object.entries(object)
|
||||
.sort(([, { [sortKey]: order1 }], [, { [sortKey]: order2 }]) => order1 - order2)
|
||||
.map(([key]) => key);
|
||||
|
||||
/**
|
||||
* @param ip
|
||||
* @returns {[IPv4|IPv6, 33|129]}
|
||||
*/
|
||||
const getParsedIpWithPrefixLength = (ip) => {
|
||||
const MAX_PREFIX_LENGTH_V4 = 32;
|
||||
const MAX_PREFIX_LENGTH_V6 = 128;
|
||||
|
||||
const parsedIp = ipaddr.parse(ip);
|
||||
const prefixLength = parsedIp.kind() === 'ipv4' ? MAX_PREFIX_LENGTH_V4 : MAX_PREFIX_LENGTH_V6;
|
||||
|
||||
// Increment prefix length to always put IP after CIDR, e.g. 127.0.0.1/32, 127.0.0.1
|
||||
return [parsedIp, prefixLength + 1];
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function for IP and CIDR comparison (supports both v4 and v6)
|
||||
* @param item - ip or cidr
|
||||
* @returns {number[]}
|
||||
*/
|
||||
const getAddressesComparisonBytes = (item) => {
|
||||
// Sort ipv4 before ipv6
|
||||
const IP_V4_COMPARISON_CODE = 0;
|
||||
const IP_V6_COMPARISON_CODE = 1;
|
||||
|
||||
const [parsedIp, cidr] = ipaddr.isValid(item)
|
||||
? getParsedIpWithPrefixLength(item)
|
||||
: ipaddr.parseCIDR(item);
|
||||
|
||||
const [normalizedBytes, ipVersionComparisonCode] = parsedIp.kind() === 'ipv4'
|
||||
? [parsedIp.toIPv4MappedAddress().parts, IP_V4_COMPARISON_CODE]
|
||||
: [parsedIp.parts, IP_V6_COMPARISON_CODE];
|
||||
|
||||
return [ipVersionComparisonCode, ...normalizedBytes, cidr];
|
||||
};
|
||||
|
||||
/**
|
||||
* Compare function for IP and CIDR sort in ascending order (supports both v4 and v6)
|
||||
* @param a
|
||||
* @param b
|
||||
* @returns {number} -1 | 0 | 1
|
||||
*/
|
||||
export const sortIp = (a, b) => {
|
||||
try {
|
||||
const comparisonBytesA = getAddressesComparisonBytes(a);
|
||||
const comparisonBytesB = getAddressesComparisonBytes(b);
|
||||
|
||||
for (let i = 0; i < comparisonBytesA.length; i += 1) {
|
||||
const byteA = comparisonBytesA[i];
|
||||
const byteB = comparisonBytesB[i];
|
||||
|
||||
if (byteA === byteB) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
return byteA > byteB ? 1 : -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue