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(a)linux.vnet.ibm.com>
---
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'>