initial commit: @arbiter/core authorization engine with js-rigor hardening
Zanzibar-style authorization graph engine (direct/chain/TTU/defeasible/ binary modes, condensed snapshots, value relations) with 39 rigor test campaigns. Includes fixes for snapshot binary writer/reader format mismatch (snapshot-of-snapshot corruption), possibility write-boundary validation, empty-graph snapshot serialization, relation lookup cache direction collision, config-redefinition cache invalidation, binary threshold semantics, defeasible compiled routing, and comparator reason whitelisting.
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* Optimized IP Address Utilities
|
||||
*
|
||||
* High-performance versions for hot paths
|
||||
*/
|
||||
|
||||
// CIDR cache for repeated lookups
|
||||
const cidrCache = new Map();
|
||||
const CIDR_CACHE_SIZE = 1000;
|
||||
|
||||
/**
|
||||
* Fast IPv4 check - less strict but much faster
|
||||
* Only validates format, not strict numeric ranges
|
||||
*/
|
||||
export function isIPv4Fast(ip) {
|
||||
if (typeof ip !== 'string') return false;
|
||||
|
||||
// Quick length check (min: 7 for "0.0.0.0", max: 15 for "255.255.255.255")
|
||||
if (ip.length < 7 || ip.length > 15) return false;
|
||||
|
||||
let dots = 0;
|
||||
for (let i = 0; i < ip.length; i++) {
|
||||
const c = ip.charCodeAt(i);
|
||||
if (c === 46) { // '.'
|
||||
dots++;
|
||||
} else if (c < 48 || c > 57) { // not 0-9
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return dots === 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ultra-fast IP to integer conversion
|
||||
* Direct character parsing, no string splitting
|
||||
*/
|
||||
export function ipToIntFast(ip) {
|
||||
let result = 0;
|
||||
let octet = 0;
|
||||
let shift = 24;
|
||||
|
||||
for (let i = 0; i < ip.length; i++) {
|
||||
const c = ip.charCodeAt(i);
|
||||
if (c === 46) { // '.'
|
||||
result |= (octet << shift);
|
||||
octet = 0;
|
||||
shift -= 8;
|
||||
} else {
|
||||
octet = octet * 10 + (c - 48);
|
||||
}
|
||||
}
|
||||
|
||||
return (result | octet) >>> 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast CIDR parsing with caching
|
||||
*/
|
||||
export function parseCidrCached(cidr) {
|
||||
// Check cache first
|
||||
let cached = cidrCache.get(cidr);
|
||||
if (cached) return cached;
|
||||
|
||||
// Parse and cache
|
||||
const slashIdx = cidr.indexOf('/');
|
||||
if (slashIdx === -1) return null;
|
||||
|
||||
const ip = cidr.slice(0, slashIdx);
|
||||
const prefix = parseInt(cidr.slice(slashIdx + 1), 10);
|
||||
const mask = -1 << (32 - prefix);
|
||||
|
||||
cached = {
|
||||
network: ipToIntFast(ip),
|
||||
mask,
|
||||
prefix
|
||||
};
|
||||
|
||||
// Simple LRU - clear if too big
|
||||
if (cidrCache.size >= CIDR_CACHE_SIZE) {
|
||||
cidrCache.clear();
|
||||
}
|
||||
cidrCache.set(cidr, cached);
|
||||
|
||||
return cached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ultra-fast IP in CIDR check
|
||||
* Uses caching and optimized parsing
|
||||
*/
|
||||
export function isIpInCidrFast(ip, cidr) {
|
||||
const cached = parseCidrCached(cidr);
|
||||
if (!cached) return false;
|
||||
|
||||
const ipInt = ipToIntFast(ip);
|
||||
return (ipInt & cached.mask) === (cached.network & cached.mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast private IP check using bit manipulation
|
||||
*/
|
||||
export function isPrivateIpFast(ip) {
|
||||
const ipInt = ipToIntFast(ip);
|
||||
|
||||
// 10.0.0.0/8: 0x0A000000 to 0x0AFFFFFF
|
||||
if ((ipInt >>> 24) === 10) return true;
|
||||
|
||||
// 172.16.0.0/12: 0xAC100000 to 0xAC1FFFFF
|
||||
const high16 = ipInt >>> 16;
|
||||
if (high16 >= 0xAC10 && high16 <= 0xAC1F) return true;
|
||||
|
||||
// 192.168.0.0/16: 0xC0A80000 to 0xC0A8FFFF
|
||||
if (high16 === 0xC0A8) return true;
|
||||
|
||||
// 127.0.0.0/8: 0x7F000000 to 0x7FFFFFFF
|
||||
if ((ipInt >>> 24) === 127) return true;
|
||||
|
||||
// 169.254.0.0/16: 0xA9FE0000 to 0xA9FEFFFF
|
||||
if (high16 === 0xA9FE) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimized built-in function evaluator
|
||||
* Direct dispatch without object lookups
|
||||
*/
|
||||
export function evaluateBuiltInFast(name, args) {
|
||||
switch (name) {
|
||||
case 'ip_in_cidr':
|
||||
return isIpInCidrFast(args[0], args[1]);
|
||||
case 'ip_is_private':
|
||||
return isPrivateIpFast(args[0]);
|
||||
case 'ip_is_loopback':
|
||||
return (ipToIntFast(args[0]) >>> 24) === 127;
|
||||
case 'ip_version':
|
||||
return isIPv4Fast(args[0]) ? 4 : (args[0].includes(':') ? 6 : null);
|
||||
case 'ip_equals':
|
||||
return args[0] === args[1];
|
||||
case 'contains':
|
||||
return String(args[0]).includes(String(args[1]));
|
||||
case 'starts_with':
|
||||
return String(args[0]).startsWith(String(args[1]));
|
||||
case 'ends_with':
|
||||
return String(args[0]).endsWith(String(args[1]));
|
||||
case 'equals':
|
||||
return args[0] === args[1];
|
||||
case 'greater_than':
|
||||
return args[0] > args[1];
|
||||
case 'less_than':
|
||||
return args[0] < args[1];
|
||||
case 'in_range':
|
||||
return args[0] >= args[1] && args[0] <= args[2];
|
||||
case 'hour_of_day':
|
||||
return new Date(args[0]).getHours();
|
||||
case 'day_of_week':
|
||||
return new Date(args[0]).getDay();
|
||||
default:
|
||||
throw new Error(`Unknown: ${name}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-export original functions for compatibility
|
||||
export { isIPv4, isIPv6, isLoopbackIp, getIpVersion, normalizeIp } from './ip-utils.js';
|
||||
export { isIpInCidr, isPrivateIp } from './ip-utils.js';
|
||||
Reference in New Issue
Block a user