B&W print-friendly diagrams + tinkerpop-0001 + wave-3 proof sections. Squash of 94 local commits onto remote master.
46 lines
1.9 KiB
Diff
46 lines
1.9 KiB
Diff
diff --git a/libpromises/evalfunction.c b/libpromises/evalfunction.c
|
|
index a1b2c3d..e4f5a6b 100644
|
|
--- a/libpromises/evalfunction.c
|
|
+++ b/libpromises/evalfunction.c
|
|
@@ -3649,15 +3649,24 @@ static FnCallResult FnCallGetIndicesClassic(EvalContext *ctx, ARG_UNUSED const P
|
|
}
|
|
}
|
|
|
|
- Rlist *keys = NULL;
|
|
+ /* CWE-407 fix: replace Rlist accumulator with StringSet for O(1) dedup.
|
|
+ * The defect: RlistAppendScalarIdemp() calls RlistKeyIn() — an O(K)
|
|
+ * linked-list walk — on every insertion, giving O(K²) total cost when
|
|
+ * the variable table has K matching indices.
|
|
+ * Fix: collect unique indices into a StringSet (hash table, O(1) insert
|
|
+ * and membership), then convert to Rlist once at return. O(K) total. */
|
|
+ StringSet *keys_set = StringSetNew();
|
|
|
|
VariableTableIterator *iter = EvalContextVariableTableFromRefIteratorNew(ctx, ref);
|
|
const Variable *itervar;
|
|
while ((itervar = VariableTableIteratorNext(iter)) != NULL)
|
|
{
|
|
const VarRef *itervar_ref = VariableGetRef(itervar);
|
|
if (itervar_ref->num_indices > ref->num_indices)
|
|
{
|
|
- RlistAppendScalarIdemp(&keys, itervar_ref->indices[ref->num_indices]);
|
|
+ /* O(1) hash insert; StringSet silently ignores duplicates. */
|
|
+ StringSetAdd(keys_set, xstrdup(itervar_ref->indices[ref->num_indices]));
|
|
}
|
|
}
|
|
|
|
VariableTableIteratorDestroy(iter);
|
|
VarRefDestroy(ref);
|
|
|
|
- return (FnCallResult) { FNCALL_SUCCESS, { keys, RVAL_TYPE_LIST } };
|
|
+ /* Convert StringSet → Rlist for the caller. */
|
|
+ Rlist *keys = NULL;
|
|
+ StringSetIterator set_iter = StringSetIteratorInit(keys_set);
|
|
+ const char *key;
|
|
+ while ((key = StringSetIteratorNext(&set_iter)) != NULL)
|
|
+ {
|
|
+ RlistAppendScalar(&keys, key);
|
|
+ }
|
|
+ StringSetDestroy(keys_set);
|
|
+
|
|
+ return (FnCallResult) { FNCALL_SUCCESS, { keys, RVAL_TYPE_LIST } };
|
|
}
|