On 5/4/21 1:40 PM, Kristina Hanicova wrote:
Signed-off-by: Kristina Hanicova <khanicov(a)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