fix(v4): a manage request with too few values, or no room, is refused (#169)
v4_manage_serve took its arguments with v4_dstack_pop and never checked the stack's depth: a request with too few values acted on stale ring values, and one whose results did not fit dropped the oldest silently -- around the D-16 guards. Now each request's arity (manage.h) is checked first: fewer values than it takes, or no room for what it leaves, is error 12 with the stack as it was -- as a block request is refused (blocks.c). test_manage.c, written first and seen to fail (12 of 13 requests at both cell widths; NODE-BORN passed only because the stale value read was below 1): every request with one value fewer than it takes, and NODE-ME and CAPSULE-CELL on a stack with no room -- refused, the stack unchanged. After: 78 checks, 0 failures at 32 and 64 bits; all v4 tests at 64 bits, 40 programs, 1,871,313 checks, 0 failures (logs/20261112-152602/v4-test). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017RzZgrf7V7Zk2iczBXDRbm
This commit is contained in:
@@ -87,15 +87,25 @@ int v4_manage_enter(const v4_manage *m, v4_cell number, unsigned place, v4_cell
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The values each request takes from the asker's stack and leaves there, from NODE-ME (-6) to
|
||||
* NODE-PLACE (-18), as manage.h gives them: a request with fewer, or with no room for what it
|
||||
* leaves, is refused before anything is taken (#169) -- as a block request is (blocks.c). */
|
||||
static const unsigned char req_in[13] = { 0, 1, 4, 2, 1, 1, 1, 2, 2, 0, 1, 2, 1 };
|
||||
static const unsigned char req_out[13] = { 1, 1, 1, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1 };
|
||||
|
||||
int v4_manage_serve(const v4_manage *m, unsigned place, v4_cell request)
|
||||
{
|
||||
v4_fabric_node *at = v4_fabric_node_at(m->f, place);
|
||||
v4_manage_entry *me, *e;
|
||||
v4_node *n;
|
||||
v4_cell a, b, c, d;
|
||||
unsigned in, out;
|
||||
|
||||
if (!at || request > V4_REQ_NODE_ME || request < V4_REQ_NODE_PLACE) return 0;
|
||||
n = &at->n;
|
||||
in = req_in[V4_REQ_NODE_ME - request];
|
||||
out = req_out[V4_REQ_NODE_ME - request];
|
||||
if (n->ds.depth < in || n->ds.depth - in + out > V4_DATA_DEPTH) return refuse(n);
|
||||
me = by_place(m, place);
|
||||
|
||||
switch (request) {
|
||||
|
||||
Reference in New Issue
Block a user