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

Function cross_join_with_rels

src/cypher/cypher.c:4202–4243  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

4200
4201/* Cross-join pattern-with-rels into existing bindings */
4202static void cross_join_with_rels(cbm_store_t *store, cbm_pattern_t *patn, binding_t **bindings,
4203 int *bind_count, cbm_node_t *extra_nodes, int extra_count,
4204 const char *nvar, bool opt) {
4205 /* size_t arithmetic: bind_count * extra_count can exceed INT_MAX on large
4206 * graphs (e.g. an unbound `c` scanned against ~29 K `f` bindings), wrapping
4207 * the int product negative and yielding a tiny/garbage malloc → heap OOB
4208 * write → SIGSEGV/SIGABRT (#627). */
4209 size_t alloc_n = (size_t)*bind_count * (size_t)extra_count * (size_t)CYP_GROWTH_10 + SKIP_ONE;
4210 binding_t *new_bindings = malloc(alloc_n * sizeof(binding_t));
4211 if (!new_bindings) {
4212 return; /* OOM: leave existing bindings untouched rather than corrupt */
4213 }
4214 int new_count = 0;
4215 for (int bi = 0; bi < *bind_count; bi++) {
4216 for (int ni = 0; ni < extra_count; ni++) {
4217 binding_t nb = {0};
4218 binding_copy(&nb, &(*bindings)[bi]);
4219 binding_set(&nb, nvar, &extra_nodes[ni]);
4220 binding_t *tmp = malloc(PAIR_LEN * sizeof(binding_t));
4221 tmp[0] = nb;
4222 int tc = SKIP_ONE;
4223 int tcap = SKIP_ONE;
4224 const char *tv = nvar;
4225 expand_pattern_rels(store, patn, &tmp, &tc, &tcap, &tv, opt);
4226 for (int ti = 0; ti < tc; ti++) {
4227 new_bindings[new_count++] = tmp[ti];
4228 }
4229 free(tmp);
4230 }
4231 if (opt && extra_count == 0) {
4232 binding_t nb = {0};
4233 binding_copy(&nb, &(*bindings)[bi]);
4234 new_bindings[new_count++] = nb;
4235 }
4236 }
4237 for (int bi = 0; bi < *bind_count; bi++) {
4238 binding_free(&(*bindings)[bi]);
4239 }
4240 free(*bindings);
4241 *bindings = new_bindings;
4242 *bind_count = new_count;
4243}
4244
4245/* Drive a single-relationship additional pattern from its ALREADY-BOUND
4246 * 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