Use g_strsplit to split the string and avoid use of stack'd strings. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/libxl/xen_common.c | 136 ++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 90 deletions(-) diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c index 781483f496..09c74dcb53 100644 --- a/src/libxl/xen_common.c +++ b/src/libxl/xen_common.c @@ -1141,104 +1141,61 @@ xenParseVif(char *entry, const char *vif_typename) { virDomainNetDefPtr net = NULL; virDomainNetDefPtr ret = NULL; - char *script = NULL; - char model[10]; - char type[10]; - char ip[128]; - char mac[18]; - char bridge[50]; - char vifname[50]; - char rate[50]; - char *key; - - bridge[0] = '\0'; - mac[0] = '\0'; - ip[0] = '\0'; - model[0] = '\0'; - type[0] = '\0'; - vifname[0] = '\0'; - rate[0] = '\0'; - - key = entry; - while (key) { - char *data; - char *nextkey = strchr(key, ','); - - if (!(data = strchr(key, '='))) + g_auto(GStrv) keyvals = NULL; + GStrv keyval; + g_autofree char *script = NULL; + g_autofree char *model = NULL; + g_autofree char *type = NULL; + g_autofree char *ip = NULL; + g_autofree char *mac = NULL; + g_autofree char *bridge = NULL; + g_autofree char *vifname = NULL; + g_autofree char *rate = NULL; + + keyvals = g_strsplit(entry, ",", 0); + + for (keyval = keyvals; keyval && *keyval; keyval++) { + const char *key = *keyval; + char *val = strchr(key, '='); + + virSkipSpaces(&key); + + if (!val) return NULL; - data++; + + val++; if (STRPREFIX(key, "mac=")) { - int len = nextkey ? (nextkey - data) : strlen(data); - if (virStrncpy(mac, data, len, sizeof(mac)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("MAC address %s too big for destination"), - data); - return NULL; - } + g_clear_pointer(&mac, g_free); + mac = g_strdup(val); } else if (STRPREFIX(key, "bridge=")) { - int len = nextkey ? (nextkey - data) : strlen(data); - if (virStrncpy(bridge, data, len, sizeof(bridge)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Bridge %s too big for destination"), - data); - return NULL; - } + g_clear_pointer(&bridge, g_free); + bridge = g_strdup(val); } else if (STRPREFIX(key, "script=")) { - int len = nextkey ? (nextkey - data) : strlen(data); - VIR_FREE(script); - script = g_strndup(data, len); + g_clear_pointer(&script, g_free); + script = g_strdup(val); } else if (STRPREFIX(key, "model=")) { - int len = nextkey ? (nextkey - data) : strlen(data); - if (virStrncpy(model, data, len, sizeof(model)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Model %s too big for destination"), - data); - return NULL; - } + g_clear_pointer(&model, g_free); + model = g_strdup(val); } else if (STRPREFIX(key, "type=")) { - int len = nextkey ? (nextkey - data) : strlen(data); - if (virStrncpy(type, data, len, sizeof(type)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Type %s too big for destination"), - data); - return NULL; - } + g_clear_pointer(&type, g_free); + type = g_strdup(val); } else if (STRPREFIX(key, "vifname=")) { - int len = nextkey ? (nextkey - data) : strlen(data); - if (virStrncpy(vifname, data, len, sizeof(vifname)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Vifname %s too big for destination"), - data); - return NULL; - } + g_clear_pointer(&vifname, g_free); + vifname = g_strdup(val); } else if (STRPREFIX(key, "ip=")) { - int len = nextkey ? (nextkey - data) : strlen(data); - if (virStrncpy(ip, data, len, sizeof(ip)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("IP %s too big for destination"), data); - return NULL; - } + g_clear_pointer(&ip, g_free); + ip = g_strdup(val); } else if (STRPREFIX(key, "rate=")) { - int len = nextkey ? (nextkey - data) : strlen(data); - if (virStrncpy(rate, data, len, sizeof(rate)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("rate %s too big for destination"), data); - return NULL; - } + g_clear_pointer(&rate, g_free); + rate = g_strdup(val); } - - while (nextkey && (nextkey[0] == ',' || - nextkey[0] == ' ' || - nextkey[0] == '\t')) - nextkey++; - key = nextkey; } if (!(net = virDomainNetDefNew(NULL))) goto cleanup; - if (mac[0]) { + if (mac) { if (virMacAddrParse(mac, &net->mac) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("malformed mac address '%s'"), mac); @@ -1246,18 +1203,18 @@ xenParseVif(char *entry, const char *vif_typename) } } - if (bridge[0] || STREQ_NULLABLE(script, "vif-bridge") || + if (bridge || STREQ_NULLABLE(script, "vif-bridge") || STREQ_NULLABLE(script, "vif-vnic")) { net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; } else { net->type = VIR_DOMAIN_NET_TYPE_ETHERNET; } - if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE && bridge[0]) { + if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE && bridge) { if (xenParseVifBridge(net, bridge) < 0) goto cleanup; } - if (ip[0]) { + if (ip) { char **ip_list = g_strsplit(ip, " ", 0); size_t i; @@ -1276,18 +1233,18 @@ xenParseVif(char *entry, const char *vif_typename) if (script && script[0]) net->script = g_strdup(script); - if (model[0]) { + if (model) { if (virDomainNetSetModelString(net, model) < 0) goto cleanup; } else { - if (type[0] && STREQ(type, vif_typename)) + if (type && STREQ(type, vif_typename)) net->model = VIR_DOMAIN_NET_MODEL_NETFRONT; } - if (vifname[0]) + if (vifname && vifname[0]) net->ifname = g_strdup(vifname); - if (rate[0]) { + if (rate) { virNetDevBandwidthPtr bandwidth; unsigned long long kbytes_per_sec; @@ -1304,7 +1261,6 @@ xenParseVif(char *entry, const char *vif_typename) cleanup: virDomainNetDefFree(net); - VIR_FREE(script); return ret; } -- 2.29.2