Address side effects of accessing vars via index

Address side effect of accessing a variable via an index: Filters
accessing a variable where an element is accessed that is beyond the
size of the list (for example $TEST[10] and only 2 elements are available)
cannot instantiate that filter. Test for this and report proper error
to user.
This commit is contained in:
Stefan Berger 2012-01-11 06:42:37 -05:00 committed by Stefan Berger
parent caa6223a9b
commit 64484d550d
4 changed files with 53 additions and 8 deletions

View File

@ -1072,3 +1072,32 @@ virNWFilterVarAccessGetIntIterId(const virNWFilterVarAccessPtr vap)
{ {
return vap->u.index.intIterId; return vap->u.index.intIterId;
} }
bool
virNWFilterVarAccessIsAvailable(const virNWFilterVarAccessPtr varAccess,
const virNWFilterHashTablePtr hash)
{
const char *varName = virNWFilterVarAccessGetVarName(varAccess);
const char *res;
unsigned int idx;
virNWFilterVarValuePtr varValue;
varValue = virHashLookup(hash->hashTable, varName);
if (!varValue)
return false;
switch (virNWFilterVarAccessGetType(varAccess)) {
case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
idx = virNWFilterVarAccessGetIndex(varAccess);
res = virNWFilterVarValueGetNthValue(varValue, idx);
if (res == NULL)
return false;
break;
case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
break;
case VIR_NWFILTER_VAR_ACCESS_LAST:
return false;
}
return true;
}

View File

@ -125,7 +125,8 @@ enum virNWFilterVarAccessType virNWFilterVarAccessGetType(
const virNWFilterVarAccessPtr vap); const virNWFilterVarAccessPtr vap);
unsigned int virNWFilterVarAccessGetIterId(const virNWFilterVarAccessPtr vap); unsigned int virNWFilterVarAccessGetIterId(const virNWFilterVarAccessPtr vap);
unsigned int virNWFilterVarAccessGetIndex(const virNWFilterVarAccessPtr vap); unsigned int virNWFilterVarAccessGetIndex(const virNWFilterVarAccessPtr vap);
bool virNWFilterVarAccessIsAvailable(const virNWFilterVarAccessPtr vap,
const virNWFilterHashTablePtr hash);
typedef struct _virNWFilterVarCombIterEntry virNWFilterVarCombIterEntry; typedef struct _virNWFilterVarCombIterEntry virNWFilterVarCombIterEntry;
typedef virNWFilterVarCombIterEntry *virNWFilterVarCombIterEntryPtr; typedef virNWFilterVarCombIterEntry *virNWFilterVarCombIterEntryPtr;

View File

@ -833,6 +833,8 @@ virNWFilterHashTablePut;
virNWFilterHashTablePutAll; virNWFilterHashTablePutAll;
virNWFilterHashTableRemoveEntry; virNWFilterHashTableRemoveEntry;
virNWFilterVarAccessGetVarName; virNWFilterVarAccessGetVarName;
virNWFilterVarAccessIsAvailable;
virNWFilterVarAccessPrint;
virNWFilterVarCombIterCreate; virNWFilterVarCombIterCreate;
virNWFilterVarCombIterFree; virNWFilterVarCombIterFree;
virNWFilterVarCombIterGetVarValue; virNWFilterVarCombIterGetVarValue;

View File

@ -501,16 +501,29 @@ virNWFilterDetermineMissingVarsRec(virNWFilterDefPtr filter,
if (rule) { if (rule) {
/* check all variables of this rule */ /* check all variables of this rule */
for (j = 0; j < rule->nVarAccess; j++) { for (j = 0; j < rule->nVarAccess; j++) {
const char *varName; if (!virNWFilterVarAccessIsAvailable(rule->varAccess[j],
varName = virNWFilterVarAccessGetVarName(rule->varAccess[j]); vars)) {
if (!virHashLookup(vars->hashTable, varName)) { const char *varAccess;
val = virNWFilterVarValueCreateSimpleCopyValue("1"); virBuffer buf = VIR_BUFFER_INITIALIZER;
if (!val) {
virNWFilterVarAccessPrint(rule->varAccess[j], &buf);
if (virBufferError(&buf)) {
virReportOOMError();
rc = -1; rc = -1;
break; break;
} }
virNWFilterHashTablePut(missing_vars, varName,
val = virNWFilterVarValueCreateSimpleCopyValue("1");
if (!val) {
virBufferFreeAndReset(&buf);
rc = -1;
break;
}
varAccess = virBufferContentAndReset(&buf);
virNWFilterHashTablePut(missing_vars, varAccess,
val, 1); val, 1);
VIR_FREE(varAccess);
} }
} }
if (rc) if (rc)
@ -752,7 +765,7 @@ err_unresolvable_vars:
if (buf) { if (buf) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("Cannot instantiate filter due to unresolvable " _("Cannot instantiate filter due to unresolvable "
"variables: %s"), buf); "variables or unavailable list elements: %s"), buf);
VIR_FREE(buf); VIR_FREE(buf);
} }