PromiseResult ExpandPromise(EvalContext *ctx, const Promise *pp, PromiseActuator *ActOnPromise, void *param) { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; Promise *pcopy = DeRefCopyPromise(ctx, pp); MapIteratorsFromRval(ctx, PromiseGetBundle(pp), (Rval) { pcopy->promiser, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); if (pcopy->promisee.item != NULL) { MapIteratorsFromRval(ctx, PromiseGetBundle(pp), pp->promisee, &scalars, &lists, &containers); } for (size_t i = 0; i < SeqLength(pcopy->conlist); i++) { Constraint *cp = SeqAt(pcopy->conlist, i); MapIteratorsFromRval(ctx, PromiseGetBundle(pp), cp->rval, &scalars, &lists, &containers); } CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), lists); CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), scalars); CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), containers); PromiseResult result = ExpandPromiseAndDo(ctx, pcopy, lists, containers, ActOnPromise, param); PromiseDestroy(pcopy); RlistDestroy(lists); RlistDestroy(scalars); RlistDestroy(containers); return result; }
void TestExpandVariables() { Promise pp = { 0 }, *pcopy; Rlist *args, *listvars = NULL, *scalarvars = NULL; Constraint *cp; FnCall *fp; strcpy(CFWORKDIR, GetWorkDir()); MapName(CFWORKDIR); /* Still have diagnostic scope */ NewScope("control_common"); printf("%d. Testing variable expansion\n", ++NR); pp.promiser = "the originator"; pp.promisee = (Rval) {"the recipient with $(two)", CF_SCALAR}; pp.classes = "proletariat"; pp.offset.line = 12; pp.audit = NULL; pp.conlist = NULL; pp.agentsubtype = "none"; pp.bundletype = "bundle_type"; pp.bundle = "test_bundle"; pp.ref = "commentary"; pp.agentsubtype = xstrdup("files"); pp.done = false; pp.next = NULL; pp.cache = NULL; pp.inode_cache = NULL; pp.this_server = NULL; pp.donep = &(pp.done); pp.conn = NULL; args = SplitStringAsRList("$(administrator)", ','); fp = NewFnCall("getuid", args); AppendConstraint(&(pp.conlist), "lval1", (Rval) {xstrdup("@(one)"), CF_SCALAR}, "lower classes1", false); AppendConstraint(&(pp.conlist), "lval2", (Rval) {xstrdup("$(four)"), CF_SCALAR}, "upper classes1", false); AppendConstraint(&(pp.conlist), "lval3", (Rval) {fp, CF_FNCALL}, "upper classes2", false); /* Now copy promise and delete */ pcopy = DeRefCopyPromise("diagnostic", &pp); MapIteratorsFromRval("diagnostic", &scalarvars, &listvars, (Rval) {pcopy->promiser, CF_SCALAR}, NULL); if (pcopy->promisee.item != NULL) { MapIteratorsFromRval("diagnostic", &scalarvars, &listvars, pp.promisee, NULL); } for (cp = pcopy->conlist; cp != NULL; cp = cp->next) { MapIteratorsFromRval("diagnostic", &scalarvars, &listvars, cp->rval, NULL); } ExpandPromiseAndDo(cf_common, "diagnostic", pcopy, scalarvars, listvars, NULL); /* No cleanup */ }
/** * Recursively go down the #rval and run PromiseIteratorPrepare() to take note * of all iterables and mangle all rvals than need to be mangled before * iterating. */ static void MapIteratorsFromRval(EvalContext *ctx, PromiseIterator *iterctx, Rval rval) { switch (rval.type) { case RVAL_TYPE_SCALAR: PromiseIteratorPrepare(iterctx, ctx, RvalScalarValue(rval)); break; case RVAL_TYPE_LIST: for (const Rlist *rp = RvalRlistValue(rval); rp != NULL; rp = rp->next) { MapIteratorsFromRval(ctx, iterctx, rp->val); } break; case RVAL_TYPE_FNCALL: { char *fn_name = RvalFnCallValue(rval)->name; /* Check function name. */ PromiseIteratorPrepare(iterctx, ctx, fn_name); /* Check each of the function arguments. */ /* EXCEPT on functions that use special variables: the mangled * variables would never be resolved if they contain inner special * variables (for example "$(bundle.A[$(this.k)])" and the returned * slist would contained mangled vars like "bundle#A[1]" which would * never resolve in future iterations. By skipping the iteration * engine for now, the function returns an slist with unmangled * entries, and the iteration engine works correctly on the next * pass! */ if (strcmp(fn_name, "maplist") != 0 && strcmp(fn_name, "mapdata") != 0 && strcmp(fn_name, "maparray")!= 0) { for (Rlist *rp = RvalFnCallValue(rval)->args; rp != NULL; rp = rp->next) { MapIteratorsFromRval(ctx, iterctx, rp->val); } } break; } case RVAL_TYPE_CONTAINER: case RVAL_TYPE_NOPROMISEE: break; } }
PromiseResult ExpandPromise(EvalContext *ctx, const Promise *pp, PromiseActuator *ActOnPromise, void *param) { Log(LOG_LEVEL_VERBOSE, "Evaluating promise '%s'", pp->promiser); if (!IsDefinedClass(ctx, pp->classes)) { if (LEGACY_OUTPUT) { Log(LOG_LEVEL_VERBOSE, ". . . . . . . . . . . . . . . . . . . . . . . . . . . . "); Log(LOG_LEVEL_VERBOSE, "Skipping whole next promise (%s), as context %s is not relevant", pp->promiser, pp->classes); Log(LOG_LEVEL_VERBOSE, ". . . . . . . . . . . . . . . . . . . . . . . . . . . . "); } else { Log(LOG_LEVEL_VERBOSE, "Skipping next promise '%s', as context '%s' is not relevant", pp->promiser, pp->classes); } return PROMISE_RESULT_SKIPPED; } Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; Promise *pcopy = DeRefCopyPromise(ctx, pp); MapIteratorsFromRval(ctx, PromiseGetBundle(pp), (Rval) { pcopy->promiser, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); if (pcopy->promisee.item != NULL) { MapIteratorsFromRval(ctx, PromiseGetBundle(pp), pp->promisee, &scalars, &lists, &containers); } for (size_t i = 0; i < SeqLength(pcopy->conlist); i++) { Constraint *cp = SeqAt(pcopy->conlist, i); MapIteratorsFromRval(ctx, PromiseGetBundle(pp), cp->rval, &scalars, &lists, &containers); } CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), lists); CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), scalars); CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), containers); PromiseResult result = ExpandPromiseAndDo(ctx, pcopy, lists, containers, ActOnPromise, param); PromiseDestroy(pcopy); RlistDestroy(lists); RlistDestroy(scalars); RlistDestroy(containers); return result; }
PromiseResult ExpandPromise(EvalContext *ctx, const Promise *pp, PromiseActuator *act_on_promise, void *param) { if (!IsDefinedClass(ctx, pp->classes)) { return PROMISE_RESULT_SKIPPED; } /* 1. Copy the promise while expanding '@' slists and body arguments * (including body inheritance). */ Promise *pcopy = DeRefCopyPromise(ctx, pp); EvalContextStackPushPromiseFrame(ctx, pcopy, true); PromiseIterator *iterctx = PromiseIteratorNew(pcopy); /* 2. Parse all strings (promiser-promisee-constraints), find all unexpanded variables, mangle them if needed (if they are namespaced/scoped), and start the iteration engine (iterctx) to iterate over slists and containers. */ MapIteratorsFromRval(ctx, iterctx, (Rval) { pcopy->promiser, RVAL_TYPE_SCALAR }); if (pcopy->promisee.item != NULL) { MapIteratorsFromRval(ctx, iterctx, pcopy->promisee); } for (size_t i = 0; i < SeqLength(pcopy->conlist); i++) { Constraint *cp = SeqAt(pcopy->conlist, i); MapIteratorsFromRval(ctx, iterctx, cp->rval); } /* 3. GO! */ PutHandleVariable(ctx, pcopy); PromiseResult result = ExpandPromiseAndDo(ctx, iterctx, act_on_promise, param); EvalContextStackPopFrame(ctx); PromiseIteratorDestroy(iterctx); PromiseDestroy(pcopy); return result; }
void ExpandPromise(EvalContext *ctx, Promise *pp, PromiseActuator *ActOnPromise, void *param) { Rlist *listvars = NULL; Rlist *scalars = NULL; Promise *pcopy; // Set a default for packages here...general defaults that need to come before //fix me wth a general function SetMissingDefaults SetAnyMissingDefaults(ctx, pp); ScopeClear("match"); /* in case we expand something expired accidentially */ EvalContextStackPushPromiseFrame(ctx, pp); pcopy = DeRefCopyPromise(ctx, pp); MapIteratorsFromRval(ctx, PromiseGetBundle(pp)->name, &listvars, &scalars, (Rval) { pcopy->promiser, RVAL_TYPE_SCALAR }); if (pcopy->promisee.item != NULL) { MapIteratorsFromRval(ctx, PromiseGetBundle(pp)->name, &listvars, &scalars, pp->promisee); } for (size_t i = 0; i < SeqLength(pcopy->conlist); i++) { Constraint *cp = SeqAt(pcopy->conlist, i); MapIteratorsFromRval(ctx, PromiseGetBundle(pp)->name, &listvars, &scalars, cp->rval); } CopyLocalizedIteratorsToThisScope(ctx, PromiseGetBundle(pp)->name, listvars); CopyLocalizedScalarsToThisScope(ctx, PromiseGetBundle(pp)->name, scalars); ScopePushThis(); ExpandPromiseAndDo(ctx, pcopy, listvars, ActOnPromise, param); ScopePopThis(); PromiseDestroy(pcopy); RlistDestroy(listvars); RlistDestroy(scalars); EvalContextStackPopFrame(ctx); }
void MapIteratorsFromRval(EvalContext *ctx, const Bundle *bundle, Rval rval, Rlist **scalars, Rlist **lists, Rlist **containers) { assert(rval.item); if (rval.item == NULL) { return; } switch (rval.type) { case RVAL_TYPE_SCALAR: { char *val = RvalScalarValue(rval); size_t val_len = strlen(val); ExpandAndMapIteratorsFromScalar(ctx, bundle, val, val_len, 0, scalars, lists, containers, NULL); } break; case RVAL_TYPE_LIST: for (const Rlist *rp = RvalRlistValue(rval); rp; rp = rp->next) { MapIteratorsFromRval(ctx, bundle, rp->val, scalars, lists, containers); } break; case RVAL_TYPE_FNCALL: ExpandAndMapIteratorsFromScalar(ctx, bundle, RvalFnCallValue(rval)->name, strlen(RvalFnCallValue(rval)->name), 0, scalars, lists, containers, NULL); for (const Rlist *rp = RvalFnCallValue(rval)->args; rp; rp = rp->next) { Log(LOG_LEVEL_DEBUG, "Looking at arg for function-like object '%s'", RvalFnCallValue(rval)->name); MapIteratorsFromRval(ctx, bundle, rp->val, scalars, lists, containers); } break; case RVAL_TYPE_CONTAINER: case RVAL_TYPE_NOPROMISEE: Log(LOG_LEVEL_DEBUG, "Unknown Rval type for scope '%s'", bundle->name); break; } }
void ExpandPromise(EvalContext *ctx, Promise *pp, PromiseActuator *ActOnPromise, void *param) { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; // Set a default for packages here...general defaults that need to come before //fix me wth a general function SetMissingDefaults SetAnyMissingDefaults(ctx, pp); Promise *pcopy = DeRefCopyPromise(ctx, pp); MapIteratorsFromRval(ctx, PromiseGetBundle(pp)->name, (Rval) { pcopy->promiser, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); if (pcopy->promisee.item != NULL) { MapIteratorsFromRval(ctx, PromiseGetBundle(pp)->name, pp->promisee, &scalars, &lists, &containers); } for (size_t i = 0; i < SeqLength(pcopy->conlist); i++) { Constraint *cp = SeqAt(pcopy->conlist, i); MapIteratorsFromRval(ctx, PromiseGetBundle(pp)->name, cp->rval,&scalars, &lists, &containers); } CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), lists); CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), scalars); CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), containers); ExpandPromiseAndDo(ctx, pcopy, lists, containers, ActOnPromise, param); PromiseDestroy(pcopy); RlistDestroy(lists); RlistDestroy(scalars); RlistDestroy(containers); }
void TestVariableScan() { int i; char *list_text1 = "$(administrator),a,b,c,d,e,f"; char *list_text2 = "1,2,3,4,@(one)"; Rlist *varlist1, *varlist2, *listoflists = NULL, *scalars = NULL; static char *varstrings[] = { "alpha $(one) beta $(two) gamma", "alpha $(five) beta $(none) gamma $(array[$(four)])", "alpha $(none) beta $(two) gamma", "alpha $(four) beta $(two) gamma $(array[$(diagnostic.three)])", NULL }; printf("%d. Test variable scanning\n", ++NR); SetNewScope("diagnostic"); varlist1 = SplitStringAsRList(list_text1, ','); varlist2 = SplitStringAsRList(list_text2, ','); NewList("diagnostic", "one", varlist1, cf_slist); NewScalar("diagnostic", "two", "secondary skills", cf_str); NewScalar("diagnostic", "administrator", "root", cf_str); NewList("diagnostic", "three", varlist2, cf_slist); NewList("diagnostic", "four", varlist2, cf_slist); NewList("diagnostic", "five", varlist2, cf_slist); for (i = 0; varstrings[i] != NULL; i++) { if (VERBOSE || DEBUG) { printf("-----------------------------------------------------------\n"); printf("Scanning: [%s]\n", varstrings[i]); MapIteratorsFromRval("diagnostic", &scalars, &listoflists, (Rval) { varstrings[i], CF_SCALAR }, NULL); printf("Cumulative scan produced:\n"); printf(" Scalar variables: "); ShowRlist(stdout, scalars); printf("\n"); printf(" Lists variables: "); ShowRlist(stdout, listoflists); printf("\n"); } } }
static void test_map_iterators_from_rval_literal(void **state) { EvalContext *ctx = *state; Policy *p = PolicyNew(); Bundle *bp = PolicyAppendBundle(p, "default", "none", "agent", NULL, NULL); Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; MapIteratorsFromRval(ctx, bp, (Rval) { "snookie", RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_int_equal(0, RlistLen(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); PolicyDestroy(p); }
bool EvalContextVariablePut(EvalContext *ctx, VarRef lval, Rval rval, DataType type) { Scope *ptr; const Rlist *rp; CfAssoc *assoc; if (rval.type == RVAL_TYPE_SCALAR) { CfDebug("AddVariableHash(%s.%s=%s (%s) rtype=%c)\n", lval.scope, lval.lval, (const char *) rval.item, CF_DATATYPES[type], rval.type); } else { CfDebug("AddVariableHash(%s.%s=(list) (%s) rtype=%c)\n", lval.scope, lval.lval, CF_DATATYPES[type], rval.type); } if (lval.lval == NULL || lval.scope == NULL) { CfOut(OUTPUT_LEVEL_ERROR, "", "scope.value = %s.%s", lval.scope, lval.lval); ProgrammingError("Bad variable or scope in a variable assignment, should not happen - forgotten to register a function call in fncall.c?"); } if (rval.item == NULL) { CfDebug("No value to assignment - probably a parameter in an unused bundle/body\n"); return false; } if (strlen(lval.lval) > CF_MAXVARSIZE) { char *lval_str = VarRefToString(lval); CfOut(OUTPUT_LEVEL_ERROR, "", "Variable %s cannot be added because its length exceeds the maximum length allowed: %d", lval_str, CF_MAXVARSIZE); free(lval_str); return false; } /* If we are not expanding a body template, check for recursive singularities */ if (strcmp(lval.scope, "body") != 0) { switch (rval.type) { case RVAL_TYPE_SCALAR: if (StringContainsVar((char *) rval.item, lval.lval)) { CfOut(OUTPUT_LEVEL_ERROR, "", "Scalar variable %s.%s contains itself (non-convergent): %s", lval.scope, lval.lval, (char *) rval.item); return false; } break; case RVAL_TYPE_LIST: for (rp = rval.item; rp != NULL; rp = rp->next) { if (StringContainsVar((char *) rp->item, lval.lval)) { CfOut(OUTPUT_LEVEL_ERROR, "", "List variable %s contains itself (non-convergent)", lval.lval); return false; } } break; default: break; } } ptr = ScopeGet(lval.scope); if (!ptr) { ptr = ScopeNew(lval.scope); if (!ptr) { return false; } } // Look for outstanding lists in variable rvals if (THIS_AGENT_TYPE == AGENT_TYPE_COMMON) { Rlist *listvars = NULL; if (ScopeGetCurrent() && strcmp(ScopeGetCurrent()->scope, "this") != 0) { MapIteratorsFromRval(ScopeGetCurrent()->scope, &listvars, rval); if (listvars != NULL) { CfOut(OUTPUT_LEVEL_ERROR, "", " !! Redefinition of variable \"%s\" (embedded list in RHS) in context \"%s\"", lval.lval, ScopeGetCurrent()->scope); } RlistDestroy(listvars); } } assoc = HashLookupElement(ptr->hashtable, lval.lval); if (assoc) { if (CompareVariableValue(rval, assoc) == 0) { /* Identical value, keep as is */ } else { /* Different value, bark and replace */ if (!UnresolvedVariables(assoc, rval.type)) { CfOut(OUTPUT_LEVEL_INFORM, "", " !! Duplicate selection of value for variable \"%s\" in scope %s", lval.lval, ptr->scope); } RvalDestroy(assoc->rval); assoc->rval = RvalCopy(rval); assoc->dtype = type; CfDebug("Stored \"%s\" in context %s\n", lval.lval, lval.scope); } } else { if (!HashInsertElement(ptr->hashtable, lval.lval, rval, type)) { ProgrammingError("Hash table is full"); } } CfDebug("Added Variable %s in scope %s with value (omitted)\n", lval.lval, lval.scope); return true; }
bool EvalContextVariablePut(EvalContext *ctx, VarRef lval, Rval rval, DataType type) { assert(type != DATA_TYPE_NONE); if (lval.lval == NULL || lval.scope == NULL) { ProgrammingError("Bad variable or scope in a variable assignment. scope.value = %s.%s", lval.scope, lval.lval); } if (rval.item == NULL) { return false; } if (strlen(lval.lval) > CF_MAXVARSIZE) { char *lval_str = VarRefToString(lval, true); Log(LOG_LEVEL_ERR, "Variable '%s'' cannot be added because its length exceeds the maximum length allowed '%d' characters", lval_str, CF_MAXVARSIZE); free(lval_str); return false; } // If we are not expanding a body template, check for recursive singularities if (strcmp(lval.scope, "body") != 0) { switch (rval.type) { case RVAL_TYPE_SCALAR: if (StringContainsVar((char *) rval.item, lval.lval)) { Log(LOG_LEVEL_ERR, "Scalar variable '%s.%s' contains itself (non-convergent), value '%s'", lval.scope, lval.lval, (char *) rval.item); return false; } break; case RVAL_TYPE_LIST: for (const Rlist *rp = rval.item; rp != NULL; rp = rp->next) { if (StringContainsVar(rp->item, lval.lval)) { Log(LOG_LEVEL_ERR, "List variable '%s' contains itself (non-convergent)", lval.lval); return false; } } break; default: break; } } else { assert(STACK_FRAME_TYPE_BODY == LastStackFrame(ctx, 0)->type); } Scope *put_scope = ScopeGet(lval.scope); if (!put_scope) { put_scope = ScopeNew(lval.scope); if (!put_scope) { return false; } } // Look for outstanding lists in variable rvals if (THIS_AGENT_TYPE == AGENT_TYPE_COMMON) { Rlist *listvars = NULL; Rlist *scalars = NULL; // TODO what do we do with scalars? if (ScopeGetCurrent() && strcmp(ScopeGetCurrent()->scope, "this") != 0) { MapIteratorsFromRval(ctx, ScopeGetCurrent()->scope, &listvars, &scalars, rval); if (listvars != NULL) { Log(LOG_LEVEL_ERR, "Redefinition of variable '%s' (embedded list in RHS) in context '%s'", lval.lval, ScopeGetCurrent()->scope); } RlistDestroy(listvars); RlistDestroy(scalars); } } // FIX: lval is stored with array params as part of the lval for legacy reasons. char *final_lval = VarRefToString(lval, false); CfAssoc *assoc = HashLookupElement(put_scope->hashtable, final_lval); if (assoc) { if (CompareVariableValue(rval, assoc) != 0) { /* Different value, bark and replace */ if (!UnresolvedVariables(assoc, rval.type)) { Log(LOG_LEVEL_INFO, "Replaced value of variable '%s' in scope '%s'", lval.lval, put_scope->scope); } RvalDestroy(assoc->rval); assoc->rval = RvalCopy(rval); assoc->dtype = type; } } else { if (!HashInsertElement(put_scope->hashtable, final_lval, rval, type)) { ProgrammingError("Hash table is full"); } } free(final_lval); return true; }
int AddVariableHash(const char *scope, const char *lval, Rval rval, enum cfdatatype dtype, const char *fname, int lineno) { Scope *ptr; const Rlist *rp; CfAssoc *assoc; if (rval.rtype == CF_SCALAR) { CfDebug("AddVariableHash(%s.%s=%s (%s) rtype=%c)\n", scope, lval, (const char *) rval.item, CF_DATATYPES[dtype], rval.rtype); } else { CfDebug("AddVariableHash(%s.%s=(list) (%s) rtype=%c)\n", scope, lval, CF_DATATYPES[dtype], rval.rtype); } if (lval == NULL || scope == NULL) { CfOut(cf_error, "", "scope.value = %s.%s", scope, lval); ReportError("Bad variable or scope in a variable assignment"); FatalError("Should not happen - forgotten to register a function call in fncall.c?"); } if (rval.item == NULL) { CfDebug("No value to assignment - probably a parameter in an unused bundle/body\n"); return false; } if (strlen(lval) > CF_MAXVARSIZE) { ReportError("variable lval too long"); return false; } /* If we are not expanding a body template, check for recursive singularities */ if (strcmp(scope, "body") != 0) { switch (rval.rtype) { case CF_SCALAR: if (StringContainsVar((char *) rval.item, lval)) { CfOut(cf_error, "", "Scalar variable %s.%s contains itself (non-convergent): %s", scope, lval, (char *) rval.item); return false; } break; case CF_LIST: for (rp = rval.item; rp != NULL; rp = rp->next) { if (StringContainsVar((char *) rp->item, lval)) { CfOut(cf_error, "", "List variable %s contains itself (non-convergent)", lval); return false; } } break; } } ptr = GetScope(scope); if (ptr == NULL) { return false; } // Look for outstanding lists in variable rvals if (THIS_AGENT_TYPE == cf_common) { Rlist *listvars = NULL, *scalarvars = NULL; if (strcmp(CONTEXTID, "this") != 0) { MapIteratorsFromRval(CONTEXTID, &scalarvars, &listvars, rval, NULL); if (listvars != NULL) { CfOut(cf_error, "", " !! Redefinition of variable \"%s\" (embedded list in RHS) in context \"%s\"", lval, CONTEXTID); } DeleteRlist(scalarvars); DeleteRlist(listvars); } } assoc = HashLookupElement(ptr->hashtable, lval); if (assoc) { if (CompareVariableValue(rval, assoc) == 0) { /* Identical value, keep as is */ } else { /* Different value, bark and replace */ if (!UnresolvedVariables(assoc, rval.rtype)) { CfOut(cf_inform, "", " !! Duplicate selection of value for variable \"%s\" in scope %s", lval, ptr->scope); if (fname) { CfOut(cf_inform, "", " !! Rule from %s at/before line %d\n", fname, lineno); } else { CfOut(cf_inform, "", " !! in bundle parameterization\n"); } } DeleteRvalItem(assoc->rval); assoc->rval = CopyRvalItem(rval); assoc->dtype = dtype; CfDebug("Stored \"%s\" in context %s\n", lval, scope); } } else { if (!HashInsertElement(ptr->hashtable, lval, rval, dtype)) { FatalError("Hash table is full"); } } CfDebug("Added Variable %s in scope %s with value (omitted)\n", lval, scope); return true; }
static void test_map_iterators_from_rval_naked_list_var_namespace(void **state) { EvalContext *ctx = *state; Policy *p = PolicyNew(); Bundle *bp = PolicyAppendBundle(p, "ns", "scope", "agent", NULL, NULL); { Rlist *list = NULL; RlistAppend(&list, "jersey", RVAL_TYPE_SCALAR); VarRef *lval = VarRefParse("ns:scope.jwow"); EvalContextVariablePut(ctx, lval, list, CF_DATA_TYPE_STRING_LIST, NULL); VarRefDestroy(lval); RlistDestroy(list); } EvalContextStackPushBundleFrame(ctx, bp, NULL, false); { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; MapIteratorsFromRval(ctx, bp, (Rval) { "${jwow}", RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_int_equal(1, RlistLen(lists)); assert_string_equal("jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; char *str = xstrdup("${scope.jwow}"); MapIteratorsFromRval(ctx, bp, (Rval) { str, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_string_equal("${scope#jwow}", str); free(str); assert_int_equal(1, RlistLen(lists)); assert_string_equal("scope#jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; char *str = xstrdup("${ns:scope.jwow}"); MapIteratorsFromRval(ctx, bp, (Rval) { str, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_string_equal("${ns*scope#jwow}", str); free(str); assert_int_equal(1, RlistLen(lists)); assert_string_equal("ns*scope#jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } EvalContextStackPopFrame(ctx); PolicyDestroy(p); }