snapshot restore: adversarial fuzzing + structural integrity gate
A new rigor campaign (snapshot-adversarial-fuzz) hunts malformed restore buffers: every read must succeed into a structurally sound graph or throw a clean bounded error. It surfaced three real bugs now fixed: 1. BinaryReader threw a caller-contract TypeError on Buffer/Uint8Array input (fs-style restore) instead of reading it — normalized to a DataView over the real ArrayBuffer. 2. readBytes built its slice with this.view.buffer + this.offset, ignoring view.byteOffset — pooled Buffers (byteOffset 768+) read the wrong memory region entirely, corrupting restored graphs. 3. The edge gate validated array contents but not the header count fields: a desynced edgeIndex (indices build iterates edgeIndex, not array length) turned a one-byte flip into a 13-second effective hang. The gate now cross-validates numNodes/numEdges/edgeIndex/ nextRelationId/valueCount/degreeCount against their sections, and LazyNodeIdTable bounds-guards garbage offset slices. Binary mode now carries validity on every return site (direct, logical, loop, early-termination, structural), gated like the normal path.
This commit is contained in:
@@ -649,6 +649,7 @@ export class AuthorizationChecker {
|
||||
if (_visited.has(visitKey)) {
|
||||
return {
|
||||
possibility: 0,
|
||||
validity: includeMeta ? DEFAULT_VALIDITY : minimalValidity(DEFAULT_VALIDITY),
|
||||
reason: 'cycle',
|
||||
binary: true,
|
||||
...(evaluation && { evaluation })
|
||||
@@ -659,6 +660,7 @@ export class AuthorizationChecker {
|
||||
if (visited.userKey === userKey && visited.relation === relation && visited.objectKey === objectKey) {
|
||||
return {
|
||||
possibility: 0,
|
||||
validity: includeMeta ? DEFAULT_VALIDITY : minimalValidity(DEFAULT_VALIDITY),
|
||||
reason: 'cycle',
|
||||
binary: true,
|
||||
...(evaluation && { evaluation })
|
||||
@@ -707,6 +709,13 @@ export class AuthorizationChecker {
|
||||
|
||||
return {
|
||||
possibility: directRel.possibility,
|
||||
validity: includeMeta
|
||||
? (directRel.validity !== undefined
|
||||
? buildValidity('identity', [effectiveRelation], [normalizeValidity(directRel.validity)], 1, directRel.possibility)
|
||||
: DEFAULT_VALIDITY)
|
||||
: minimalValidity(directRel.validity !== undefined
|
||||
? buildValidity('identity', [effectiveRelation], [normalizeValidity(directRel.validity)], 1, directRel.possibility)
|
||||
: DEFAULT_VALIDITY),
|
||||
reason: allow ? 'allow' : deny ? 'deny' : 'insufficient_confidence',
|
||||
binary: true,
|
||||
...(evaluation && { evaluation }),
|
||||
@@ -722,6 +731,7 @@ export class AuthorizationChecker {
|
||||
|
||||
return {
|
||||
possibility: 0,
|
||||
validity: includeMeta ? DEFAULT_VALIDITY : minimalValidity(DEFAULT_VALIDITY),
|
||||
reason: 'insufficient_confidence',
|
||||
binary: true,
|
||||
...(evaluation && { evaluation }),
|
||||
@@ -766,6 +776,7 @@ export class AuthorizationChecker {
|
||||
|
||||
return {
|
||||
possibility: resAllowPossibility || 0,
|
||||
validity: includeMeta ? (res.validity || DEFAULT_VALIDITY) : minimalValidity(res.validity || DEFAULT_VALIDITY),
|
||||
reason: allow ? 'allow' : deny ? 'deny' : 'insufficient_confidence',
|
||||
binary: true,
|
||||
...(evaluation && { evaluation }),
|
||||
@@ -779,6 +790,7 @@ export class AuthorizationChecker {
|
||||
|
||||
let maxAllow = 0;
|
||||
let maxDeny = 0;
|
||||
let bestValidity = null;
|
||||
|
||||
for (const rule of rules) {
|
||||
if (evaluation) {
|
||||
@@ -800,6 +812,7 @@ export class AuthorizationChecker {
|
||||
|
||||
if (resAllowPossibility > maxAllow) {
|
||||
maxAllow = resAllowPossibility;
|
||||
if (res.validity) bestValidity = res.validity;
|
||||
}
|
||||
|
||||
if (resDenyPossibility > maxDeny) {
|
||||
@@ -817,6 +830,7 @@ export class AuthorizationChecker {
|
||||
|
||||
return {
|
||||
possibility: maxAllow,
|
||||
validity: includeMeta ? (bestValidity || DEFAULT_VALIDITY) : minimalValidity(bestValidity || DEFAULT_VALIDITY),
|
||||
reason: 'allow',
|
||||
binary: true,
|
||||
...(evaluation && { evaluation }),
|
||||
|
||||
Reference in New Issue
Block a user