This patch introduces a parser for parsing lists of values as for example found in the XML here: <parameter name='TEST' value='[10.1.2.3,10.2.3.4, 10.1.1.1]'/> The list of values is then stored in the newly introduced data type virNWFilterVarValue. Adapt the XML schema to be able to handle lists. Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxxxxxxx> --- docs/schemas/nwfilter.rng | 29 ++++++---- src/conf/nwfilter_params.c | 123 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 138 insertions(+), 14 deletions(-) Index: libvirt-acl/src/conf/nwfilter_params.c =================================================================== --- libvirt-acl.orig/src/conf/nwfilter_params.c +++ libvirt-acl/src/conf/nwfilter_params.c @@ -616,9 +618,124 @@ isValidVarValue(const char *value) } static virNWFilterVarValuePtr -virNWFilterParseVarValue(const char *val) +virNWFilterVarValueParseAsArray(const char *val, bool verbose) +{ + unsigned int i, j, k, l; + size_t bytes_to_copy; + virNWFilterVarValuePtr res; + char stopchar; + char *item; + + i = 0; + + while (val[i] && c_isspace(val[i])) + i++; + + /* arrays start with '[' and end with ']' */ + if (val[i] == '[') { + j = strlen(val) - 1; + while (j > i && val[j] && c_isspace(val[j])) + j--; + if (val[j] != ']') { + if (verbose) + virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid array syntax")); + return NULL; + } + i++; + j--; + } else { + if (verbose) + virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, + _("Array does not start with '['")); + return NULL; + } + + if (VIR_ALLOC(res) < 0) { + virReportOOMError(); + return NULL; + } + + res->valType = NWFILTER_VALUE_TYPE_ARRAY; + + while (i <= j) { + while (c_isspace(val[i])) + i++; + if (val[i] == '"' || val[i] == '\'') { + stopchar = val[i]; + i++; + } else { + stopchar = ','; + } + /* i points to first letter in item */ + k = i; + while (k <= j && val[k] != stopchar) + k++; + /* k point to the stopchar or end of value */ + if (k > j) { + /* if end of value was reached test for proper stopchar */ + if ((stopchar == '\'' || stopchar == '"') && + val[k] != stopchar) { + virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, + _("Illegal list syntax")); + goto err_exit; + } + } + /* l points to the next char to parse for the next item */ + l = k + 1; + + if (stopchar == ',') { + k--; + /* skip trailing whitespace */ + while (k > i && c_isspace(val[k])) + k--; + } else + k--; + + bytes_to_copy = (k >= i) ? ( k - i + 1) : 0; + + item = strndup(&val[i], bytes_to_copy); + + if (!item) { + virReportOOMError(); + goto err_exit; + } + + if (virNWFilterVarValueAddValue(res, item, false) == false) { + goto err_exit; + } + + i = l; + if (stopchar != ',') { + /* search for comma */ + while (i < j && c_isspace(val[i])) + i++; + if (i <= j && val[i] != ',') { + virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, + _("Malformed list")); + goto err_exit; + } + i++; + } + } + + return res; + +err_exit: + virNWFilterVarValueFree(res); + return NULL; +} + +static virNWFilterVarValuePtr +virNWFilterVarValueParse(const char *val) { - // FIXME: only handling simple values for now, no arrays + virNWFilterVarValuePtr res; + + res = virNWFilterVarValueParseAsArray(val, false); + if (res) + return res; + + return virNWFilterVarValueCreateSimple(val, true); } @@ -645,7 +762,7 @@ virNWFilterParseParamAttributes(xmlNodeP if (nam != NULL && val != NULL) { if (!isValidVarName(nam)) goto skip_entry; - value = virNWFilterParseVarValue(val); + value = virNWFilterVarValueParse(val); if (!value) goto skip_entry; if (virNWFilterHashTablePut(table, nam, value, 1)) { Index: libvirt-acl/docs/schemas/nwfilter.rng =================================================================== --- libvirt-acl.orig/docs/schemas/nwfilter.rng +++ libvirt-acl/docs/schemas/nwfilter.rng @@ -313,14 +313,16 @@ <data type="NCName"/> </attribute> <optional> - <element name="parameter"> - <attribute name="name"> - <ref name="filter-param-name"/> - </attribute> - <attribute name="value"> - <ref name="filter-param-value"/> - </attribute> - </element> + <zeroOrMore> + <element name="parameter"> + <attribute name="name"> + <ref name="filter-param-name"/> + </attribute> + <attribute name="value"> + <ref name="filter-param-value"/> + </attribute> + </element> + </zeroOrMore> </optional> </define> @@ -869,9 +871,14 @@ </define> <define name="filter-param-value"> - <data type="string"> - <param name="pattern">[a-zA-Z0-9_\.:]+</param> - </data> + <choice> + <data type="string"> + <param name="pattern">[a-zA-Z0-9_\.:]+</param> + </data> + <data type="string"> + <param name="pattern">\[[a-zA-Z0-9_\.:,&"' ]*\]</param> + </data> + </choice> </define> <define name='action-type'> -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list