MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / cross_join_with_rels

Function cross_join_with_rels

src/cypher/cypher.c:4590–4631  ·  view source on GitHub ↗

Cross-join pattern-with-rels into existing bindings */

Source from the content-addressed store, hash-verified

4588
4589/* Cross-join pattern-with-rels into existing bindings */
4590static void cross_join_with_rels(cbm_store_t *store, cbm_pattern_t *patn, binding_t **bindings,
4591 int *bind_count, cbm_node_t *extra_nodes, int extra_count,
4592 const char *nvar, bool opt) {
4593 /* size_t arithmetic: bind_count * extra_count can exceed INT_MAX on large
4594 * graphs (e.g. an unbound `c` scanned against ~29 K `f` bindings), wrapping
4595 * the int product negative and yielding a tiny/garbage malloc → heap OOB
4596 * write → SIGSEGV/SIGABRT (#627). */
4597 size_t alloc_n = (size_t)*bind_count * (size_t)extra_count * (size_t)CYP_GROWTH_10 + SKIP_ONE;
4598 binding_t *new_bindings = malloc(alloc_n * sizeof(binding_t));
4599 if (!new_bindings) {
4600 return; /* OOM: leave existing bindings untouched rather than corrupt */
4601 }
4602 int new_count = 0;
4603 for (int bi = 0; bi < *bind_count; bi++) {
4604 for (int ni = 0; ni < extra_count; ni++) {
4605 binding_t nb = {0};
4606 binding_copy(&nb, &(*bindings)[bi]);
4607 binding_set(&nb, nvar, &extra_nodes[ni]);
4608 binding_t *tmp = malloc(PAIR_LEN * sizeof(binding_t));
4609 tmp[0] = nb;
4610 int tc = SKIP_ONE;
4611 int tcap = SKIP_ONE;
4612 const char *tv = nvar;
4613 expand_pattern_rels(store, patn, &tmp, &tc, &tcap, &tv, opt);
4614 for (int ti = 0; ti < tc; ti++) {
4615 new_bindings[new_count++] = tmp[ti];
4616 }
4617 free(tmp);
4618 }
4619 if (opt && extra_count == 0) {
4620 binding_t nb = {0};
4621 binding_copy(&nb, &(*bindings)[bi]);
4622 new_bindings[new_count++] = nb;
4623 }
4624 }
4625 for (int bi = 0; bi < *bind_count; bi++) {
4626 binding_free(&(*bindings)[bi]);
4627 }
4628 free(*bindings);
4629 *bindings = new_bindings;
4630 *bind_count = new_count;
4631}
4632
4633/* Drive a single-relationship additional pattern from its ALREADY-BOUND
4634 * terminal node, binding the unbound START var to the edge's other endpoint.

Callers 1

Calls 4

binding_copyFunction · 0.85
binding_setFunction · 0.85
expand_pattern_relsFunction · 0.85
binding_freeFunction · 0.85

Tested by

no test coverage detected