[PATCH v2 13/19] Refactoring virDomainChrSourceDefParseXML() to use XPath
Michal Prívozník
mprivozn at redhat.com
Wed May 5 07:25:27 UTC 2021
On 5/4/21 1:40 PM, Kristina Hanicova wrote:
> Signed-off-by: Kristina Hanicova <khanicov at redhat.com>
> ---
> src/conf/domain_conf.c | 190 ++++++++++++++++++++---------------------
> 1 file changed, 94 insertions(+), 96 deletions(-)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 5ac15fe9e8..c5b13783f3 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -11350,112 +11350,112 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDef *def,
> virDomainChrDef *chr_def,
> xmlXPathContextPtr ctxt)
> {
> - bool logParsed = false;
> - bool protocolParsed = false;
> - int sourceParsed = 0;
> + xmlNodePtr log = NULL;
> + xmlNodePtr protocol = NULL;
> + g_autofree xmlNodePtr *source = NULL;
> + int n = 0;
> + VIR_XPATH_NODE_AUTORESTORE(ctxt)
>
> - for (; cur; cur = cur->next) {
> - if (cur->type != XML_ELEMENT_NODE)
> - continue;
> + ctxt->node = cur;
>
> - if (virXMLNodeNameEqual(cur, "source")) {
> - /* Parse only the first source element since only one is used
> - * for chardev devices, the only exception is UDP type, where
> - * user can specify two source elements. */
> - if (sourceParsed >= 1 && def->type != VIR_DOMAIN_CHR_TYPE_UDP) {
> - virReportError(VIR_ERR_XML_ERROR, "%s",
> - _("only one source element is allowed for "
> - "character device"));
> - goto error;
> - } else if (sourceParsed >= 2) {
> - virReportError(VIR_ERR_XML_ERROR, "%s",
> - _("only two source elements are allowed for "
> - "character device"));
> - goto error;
> - }
> - sourceParsed++;
> + if ((n = virXPathNodeSet("./source", ctxt, &source)) > 0) {
> + /* Parse only the first source element since only one is used
> + * for chardev devices, the only exception is UDP type, where
> + * user can specify two source elements. */
> + if (n > 1 && def->type != VIR_DOMAIN_CHR_TYPE_UDP) {
> + virReportError(VIR_ERR_XML_ERROR, "%s",
> + _("only one source element is allowed for "
> + "character device"));
> + goto error;
> + } else if (n > 2) {
> + virReportError(VIR_ERR_XML_ERROR, "%s",
> + _("only two source elements are allowed for "
> + "character device"));
> + goto error;
> + }
>
> - switch ((virDomainChrType) def->type) {
> - case VIR_DOMAIN_CHR_TYPE_FILE:
> - if (virDomainChrSourceDefParseFile(def, cur) < 0)
> - goto error;
> - break;
> + switch ((virDomainChrType) def->type) {
> + case VIR_DOMAIN_CHR_TYPE_FILE:
> + if (virDomainChrSourceDefParseFile(def, source[0]) < 0)
> + goto error;
> + break;
>
> - case VIR_DOMAIN_CHR_TYPE_PTY:
> - /* PTY path is only parsed from live xml. */
> - if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE))
> - def->data.file.path = virXMLPropString(cur, "path");
> - break;
> + case VIR_DOMAIN_CHR_TYPE_PTY:
> + /* PTY path is only parsed from live xml. */
> + if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE))
> + def->data.file.path = virXPathString("string(./source/@path)", ctxt);
> + break;
>
> - case VIR_DOMAIN_CHR_TYPE_DEV:
> - case VIR_DOMAIN_CHR_TYPE_PIPE:
> - def->data.file.path = virXMLPropString(cur, "path");
> - break;
> + case VIR_DOMAIN_CHR_TYPE_DEV:
> + case VIR_DOMAIN_CHR_TYPE_PIPE:
> + def->data.file.path = virXPathString("string(./source/@path)", ctxt);
> + break;
>
> - case VIR_DOMAIN_CHR_TYPE_UNIX:
> - if (virDomainChrSourceDefParseUnix(def, cur, ctxt) < 0)
> - goto error;
> - break;
> + case VIR_DOMAIN_CHR_TYPE_UNIX:
> + if (virDomainChrSourceDefParseUnix(def, source[0], ctxt) < 0)
> + goto error;
> + break;
>
> - case VIR_DOMAIN_CHR_TYPE_UDP:
> - if (virDomainChrSourceDefParseUDP(def, cur) < 0)
> + case VIR_DOMAIN_CHR_TYPE_UDP:
> + if ((virDomainChrSourceDefParseUDP(def, source[0]) < 0) ||
> + (source[1] && virDomainChrSourceDefParseUDP(def, source[1]) < 0))
Ooops. While this may work by chance, it's not correct.
virXPathNodeSet() does not return a NULL terminated array. Therefore, if
n == 1, then source[0] is allocated, but source[1] is not. Fortunately,
the fix is as easy as s/source[1]/n == 2/.
> goto error;
> - break;
> + break;
Michal
More information about the libvir-list
mailing list