[libvirt] [PATCH 2/n] maint: prohibit most uses of xmlGetProp

Eric Blake eblake at redhat.com
Wed Nov 24 20:34:56 UTC 2010


Making this change makes it easier to spot the memory leaks
that will be fixed in the next patch.

* cfg.mk (sc_prohibit_xmlGetProp): New rule.
* .x-sc_prohibit_xmlGetProp: New exception.
* Makefile.am (EXTRA_DIST): Ship exception file.
* tools/virsh.c (cmdDetachInterface, cmdDetachDisk): Adjust
offenders.
* src/conf/storage_conf.c (virStoragePoolDefParseSource):
Likewise.
* src/conf/network_conf.c (virNetworkDHCPRangeDefParseXML)
(virNetworkIPParseXML): Likewise.
---

valgrind picked up a memory leak in virNetworkDHCPRangeDefParseXML,
but our use of non-idiomatic string management made it harder to
see at first glance.  This makes the few outliers consistent with
all the rest of the code base.

 .x-sc_prohibit_xmlGetProp |    1 +
 Makefile.am               |    1 +
 cfg.mk                    |    6 +++++
 src/conf/network_conf.c   |   56 ++++++++++++++++++++++----------------------
 src/conf/storage_conf.c   |    4 +-
 tools/virsh.c             |   20 ++++++++--------
 6 files changed, 48 insertions(+), 40 deletions(-)
 create mode 100644 .x-sc_prohibit_xmlGetProp

diff --git a/.x-sc_prohibit_xmlGetProp b/.x-sc_prohibit_xmlGetProp
new file mode 100644
index 0000000..f6d7ee2
--- /dev/null
+++ b/.x-sc_prohibit_xmlGetProp
@@ -0,0 +1 @@
+^src/util/xml.c$
diff --git a/Makefile.am b/Makefile.am
index d3f8876..e4d369d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,6 +39,7 @@ EXTRA_DIST = \
   .x-sc_prohibit_strncpy \
   .x-sc_prohibit_test_minus_ao \
   .x-sc_prohibit_VIR_ERR_NO_MEMORY \
+  .x-sc_prohibit_xmlGetProp \
   .x-sc_require_config_h \
   .x-sc_require_config_h_first \
   .x-sc_trailing_blank \
diff --git a/cfg.mk b/cfg.mk
index 0851f44..4c5afee 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -326,6 +326,12 @@ sc_prohibit_gethostby:
 	halt='use getaddrinfo, not gethostby*'				\
 	  $(_sc_search_regexp)

+# raw xmlGetProp requires some nasty casts
+sc_prohibit_xmlGetProp:
+	@prohibit='\<xmlGetProp *\('					\
+	halt='use virXMLPropString, not xmlGetProp'			\
+	  $(_sc_search_regexp)
+
 # Many of the function names below came from this filter:
 # git grep -B2 '\<_('|grep -E '\.c- *[[:alpha:]_][[:alnum:]_]* ?\(.*[,;]$' \
 # |sed 's/.*\.c-  *//'|perl -pe 's/ ?\(.*//'|sort -u \
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 3f2bf1f..9868250 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -222,24 +222,24 @@ virNetworkDHCPRangeDefParseXML(virNetworkDefPtr def,
             virSocketAddr saddr, eaddr;
             int range;

-            if (!(start = (char *) xmlGetProp(cur, BAD_CAST "start"))) {
+            if (!(start = virXMLPropString(cur, "start"))) {
                 cur = cur->next;
                 continue;
             }
-            if (!(end = (char *) xmlGetProp(cur, BAD_CAST "end"))) {
-                xmlFree(start);
+            if (!(end = virXMLPropString(cur, "end"))) {
+                VIR_FREE(start);
                 cur = cur->next;
                 continue;
             }

             if (virSocketParseAddr(start, &saddr, AF_UNSPEC) < 0) {
-                xmlFree(start);
-                xmlFree(end);
+                VIR_FREE(start);
+                VIR_FREE(end);
                 return -1;
             }
             if (virSocketParseAddr(end, &eaddr, AF_UNSPEC) < 0) {
-                xmlFree(start);
-                xmlFree(end);
+                VIR_FREE(start);
+                VIR_FREE(end);
                 return -1;
             }

@@ -248,14 +248,14 @@ virNetworkDHCPRangeDefParseXML(virNetworkDefPtr def,
                 virNetworkReportError(VIR_ERR_XML_ERROR,
                                       _("dhcp range '%s' to '%s' invalid"),
                                       start, end);
-                xmlFree(start);
-                xmlFree(end);
+                VIR_FREE(start);
+                VIR_FREE(end);
                 return -1;
             }

             if (VIR_REALLOC_N(def->ranges, def->nranges + 1) < 0) {
-                xmlFree(start);
-                xmlFree(end);
+                VIR_FREE(start);
+                VIR_FREE(end);
                 virReportOOMError();
                 return -1;
             }
@@ -264,19 +264,19 @@ virNetworkDHCPRangeDefParseXML(virNetworkDefPtr def,
             def->nranges++;
         } else if (cur->type == XML_ELEMENT_NODE &&
             xmlStrEqual(cur->name, BAD_CAST "host")) {
-            xmlChar *mac, *name, *ip;
+            char *mac, *name, *ip;
             unsigned char addr[6];
             virSocketAddr inaddr;

-            mac = xmlGetProp(cur, BAD_CAST "mac");
+            mac = virXMLPropString(cur, "mac");
             if ((mac != NULL) &&
-                (virParseMacAddr((const char *) mac, &addr[0]) != 0)) {
+                (virParseMacAddr(mac, &addr[0]) != 0)) {
                 virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
                                       _("cannot parse MAC address '%s'"),
                                       mac);
                 VIR_FREE(mac);
             }
-            name = xmlGetProp(cur, BAD_CAST "name");
+            name = virXMLPropString(cur, "name");
             if ((name != NULL) && (!c_isalpha(name[0]))) {
                 virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
                                       _("cannot use name address '%s'"),
@@ -292,8 +292,8 @@ virNetworkDHCPRangeDefParseXML(virNetworkDefPtr def,
                 cur = cur->next;
                 continue;
             }
-            ip = xmlGetProp(cur, BAD_CAST "ip");
-            if (virSocketParseAddr((const char *)ip, &inaddr, AF_UNSPEC) < 0) {
+            ip = virXMLPropString(cur, "ip");
+            if (virSocketParseAddr(ip, &inaddr, AF_UNSPEC) < 0) {
                 VIR_FREE(ip);
                 VIR_FREE(mac);
                 VIR_FREE(name);
@@ -307,29 +307,29 @@ virNetworkDHCPRangeDefParseXML(virNetworkDefPtr def,
                 virReportOOMError();
                 return -1;
             }
-            def->hosts[def->nhosts].mac = (char *)mac;
-            def->hosts[def->nhosts].name = (char *)name;
+            def->hosts[def->nhosts].mac = mac;
+            def->hosts[def->nhosts].name = name;
             def->hosts[def->nhosts].ip = inaddr;
             def->nhosts++;

         } else if (cur->type == XML_ELEMENT_NODE &&
             xmlStrEqual(cur->name, BAD_CAST "bootp")) {
-            xmlChar *file;
-            xmlChar *server;
+            char *file;
+            char *server;
             virSocketAddr inaddr;
             memset(&inaddr, 0, sizeof(inaddr));

-            if (!(file = xmlGetProp(cur, BAD_CAST "file"))) {
+            if (!(file = virXMLPropString(cur, "file"))) {
                 cur = cur->next;
                 continue;
             }
-            server = xmlGetProp(cur, BAD_CAST "server");
+            server = virXMLPropString(cur, "server");

             if (server &&
-                virSocketParseAddr((const char *)server, &inaddr, AF_UNSPEC) < 0)
+                virSocketParseAddr(server, &inaddr, AF_UNSPEC) < 0)
                 return -1;

-            def->bootfile = (char *)file;
+            def->bootfile = file;
             def->bootserver = inaddr;
         }

@@ -354,14 +354,14 @@ virNetworkIPParseXML(virNetworkDefPtr def,

         } else if (cur->type == XML_ELEMENT_NODE &&
             xmlStrEqual(cur->name, BAD_CAST "tftp")) {
-            xmlChar *root;
+            char *root;

-            if (!(root = xmlGetProp(cur, BAD_CAST "root"))) {
+            if (!(root = virXMLPropString(cur, "root"))) {
                 cur = cur->next;
                 continue;
             }

-            def->tftproot = (char *)root;
+            def->tftproot = root;
         }

         cur = cur->next;
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 45285de..f7f471e 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -446,14 +446,14 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
         }

         for (i = 0 ; i < nsource ; i++) {
-            xmlChar *path = xmlGetProp(nodeset[i], BAD_CAST "path");
+            char *path = virXMLPropString(nodeset[i], "path");
             if (path == NULL) {
                 VIR_FREE(nodeset);
                 virStorageReportError(VIR_ERR_XML_ERROR,
                         "%s", _("missing storage pool source device path"));
                 goto cleanup;
             }
-            source->devices[i].path = (char *)path;
+            source->devices[i].path = path;
         }
         source->ndevice = nsource;
     }
diff --git a/tools/virsh.c b/tools/virsh.c
index 0ea1930..aec7749 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -8434,7 +8434,6 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
     xmlXPathObjectPtr obj=NULL;
     xmlXPathContextPtr ctxt = NULL;
     xmlNodePtr cur = NULL;
-    xmlChar *tmp_mac = NULL;
     xmlBufferPtr xml_buf = NULL;
     char *doc, *mac =NULL, *type;
     char buf[64];
@@ -8485,10 +8484,11 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
     for (; i < obj->nodesetval->nodeNr; i++) {
         cur = obj->nodesetval->nodeTab[i]->children;
         while (cur != NULL) {
-            if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "mac")) {
-                tmp_mac = xmlGetProp(cur, BAD_CAST "address");
-                diff_mac = virMacAddrCompare ((char *) tmp_mac, mac);
-                xmlFree(tmp_mac);
+            if (cur->type == XML_ELEMENT_NODE &&
+                xmlStrEqual(cur->name, BAD_CAST "mac")) {
+                char *tmp_mac = virXMLPropString(cur, "address");
+                diff_mac = virMacAddrCompare (tmp_mac, mac);
+                VIR_FREE(tmp_mac);
                 if (!diff_mac) {
                     goto hit;
                 }
@@ -8689,7 +8689,6 @@ cmdDetachDisk(vshControl *ctl, const vshCmd *cmd)
     xmlXPathObjectPtr obj=NULL;
     xmlXPathContextPtr ctxt = NULL;
     xmlNodePtr cur = NULL;
-    xmlChar *tmp_tgt = NULL;
     xmlBufferPtr xml_buf = NULL;
     virDomainPtr dom = NULL;
     char *doc, *target;
@@ -8734,10 +8733,11 @@ cmdDetachDisk(vshControl *ctl, const vshCmd *cmd)
     for (; i < obj->nodesetval->nodeNr; i++) {
         cur = obj->nodesetval->nodeTab[i]->children;
         while (cur != NULL) {
-            if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "target")) {
-                tmp_tgt = xmlGetProp(cur, BAD_CAST "dev");
-                diff_tgt = xmlStrEqual(tmp_tgt, BAD_CAST target);
-                xmlFree(tmp_tgt);
+            if (cur->type == XML_ELEMENT_NODE &&
+                xmlStrEqual(cur->name, BAD_CAST "target")) {
+                char *tmp_tgt = virXMLPropString(cur, "dev");
+                diff_tgt = STREQ(tmp_tgt, target);
+                VIR_FREE(tmp_tgt);
                 if (diff_tgt) {
                     goto hit;
                 }
-- 
1.7.3.2




More information about the libvir-list mailing list