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

Function cross_join_with_rels

src/cypher/cypher.c:4585–4626  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

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