[libbluray-devel] [PATCH 2/2] Fixed several memory leaks in metadata parsing.

Ferdinand Holzer holzer at grg21.ac.at
Sun May 27 05:01:57 CEST 2012


libbluray needs to free strings allocated by libxml2
metadata never got freed in bd_close
bd_close wasn't called in bd_info example
---
 src/examples/bd_info.c           |    2 +
 src/libbluray/bdnav/meta_parse.c |   98
+++++++++++++++++++++++++++++---------
 src/libbluray/bluray.c           |    4 ++
 3 files changed, 82 insertions(+), 22 deletions(-)

diff --git a/src/examples/bd_info.c b/src/examples/bd_info.c
index e5d4bd2..386b8f1 100644
--- a/src/examples/bd_info.c
+++ b/src/examples/bd_info.c
@@ -175,6 +175,8 @@ int main(int argc, char *argv[])
     }
 
     _print_meta(bd_get_meta(bd));
+   
+    bd_close(bd);
 
     return 0;
 }
diff --git a/src/libbluray/bdnav/meta_parse.c
b/src/libbluray/bdnav/meta_parse.c
index 8a75145..96798a1 100644
--- a/src/libbluray/bdnav/meta_parse.c
+++ b/src/libbluray/bdnav/meta_parse.c
@@ -44,43 +44,62 @@
 #endif
 
 #ifdef HAVE_LIBXML2
+
+static xmlChar *s_title = NULL;
+static xmlChar *s_name = NULL;
+static xmlChar *s_alternative = NULL;
+static xmlChar *s_numSets = NULL;
+static xmlChar *s_setNumber = NULL;
+static xmlChar *s_tableOfContents = NULL;
+static xmlChar *s_titleName = NULL;
+static xmlChar *s_titleNumber = NULL;
+static xmlChar *s_description = NULL;
+static xmlChar *s_thumbnail = NULL;
+static xmlChar *s_href = NULL;
+static xmlChar *s_size = NULL;
+
 static void _parseManifestNode(xmlNode * a_node, META_DL *disclib)
 {
     xmlNode *cur_node = NULL;
+    xmlChar *s_temp = NULL;
 
     for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
         if (cur_node->type == XML_ELEMENT_NODE) {
-            if (xmlStrEqual(cur_node->parent->name,
xmlCharStrdup("title"))) {
-                if (xmlStrEqual(cur_node->name, xmlCharStrdup("name"))) {
-                    disclib->di_name =
(char*)xmlStrdup(xmlNodeGetContent(cur_node));
+            if (xmlStrEqual(cur_node->parent->name, s_title)) {
+                if (xmlStrEqual(cur_node->name, s_name)) {
+                    disclib->di_name = (char*)xmlNodeGetContent(cur_node);
                 }
-                if (xmlStrEqual(cur_node->name,
xmlCharStrdup("alternative"))) {
-                    disclib->di_alternative =
(char*)xmlStrdup(xmlNodeGetContent(cur_node));
+                if (xmlStrEqual(cur_node->name, s_alternative)) {
+                    disclib->di_alternative =
(char*)xmlNodeGetContent(cur_node);
                 }
-                if (xmlStrEqual(cur_node->name,
xmlCharStrdup("numSets"))) {
-                    disclib->di_num_sets =
atoi((char*)xmlNodeGetContent(cur_node));
+                if (xmlStrEqual(cur_node->name, s_numSets)) {
+                    disclib->di_num_sets = atoi((char*)(s_temp =
xmlNodeGetContent(cur_node)));
+                    X_FREE(s_temp);
                 }
-                if (xmlStrEqual(cur_node->name,
xmlCharStrdup("setNumber"))) {
-                    disclib->di_set_number =
atoi((char*)xmlNodeGetContent(cur_node));
+                if (xmlStrEqual(cur_node->name, s_setNumber)) {
+                    disclib->di_set_number = atoi((char*)(s_temp =
xmlNodeGetContent(cur_node)));
+                    X_FREE(s_temp);
                 }
             }
-            else if (xmlStrEqual(cur_node->parent->name,
xmlCharStrdup("tableOfContents"))) {
-                if (xmlStrEqual(cur_node->name,
xmlCharStrdup("titleName")) && xmlGetProp(cur_node,
xmlCharStrdup("titleNumber"))) {
+            else if (xmlStrEqual(cur_node->parent->name,
s_tableOfContents)) {
+                if (xmlStrEqual(cur_node->name, s_titleName) && (s_temp
= xmlGetProp(cur_node, s_titleNumber))) {
                     int i = disclib->toc_count;
                     disclib->toc_count++;
                     disclib->toc_entries =
realloc(disclib->toc_entries, (disclib->toc_count*sizeof(META_TITLE)));
-                    disclib->toc_entries[i].title_number = atoi((const
char*)xmlGetProp(cur_node, xmlCharStrdup("titleNumber")));
-                    disclib->toc_entries[i].title_name =
(char*)xmlStrdup(xmlNodeGetContent(cur_node));
+                    disclib->toc_entries[i].title_number = atoi((const
char*)s_temp);
+                    disclib->toc_entries[i].title_name =
(char*)xmlNodeGetContent(cur_node);
+                    X_FREE(s_temp);
                 }
             }
-            else if (xmlStrEqual(cur_node->parent->name,
xmlCharStrdup("description"))) {
-                if (xmlStrEqual(cur_node->name,
xmlCharStrdup("thumbnail")) && xmlGetProp(cur_node,
xmlCharStrdup("href"))) {
+            else if (xmlStrEqual(cur_node->parent->name, s_description)) {
+                if (xmlStrEqual(cur_node->name, s_thumbnail) && (s_temp
= xmlGetProp(cur_node, s_href))) {
                     uint8_t i = disclib->thumb_count;
                     disclib->thumb_count++;
                     disclib->thumbnails = realloc(disclib->thumbnails,
(disclib->thumb_count*sizeof(META_THUMBNAIL)));
-                    disclib->thumbnails[i].path = strdup((const
char*)xmlGetProp(cur_node, xmlCharStrdup("href")));
-                    if (xmlGetProp(cur_node, xmlCharStrdup("size"))) {
-                        sscanf((const char*)xmlGetProp(cur_node,
xmlCharStrdup("size")), "%ix%i", &disclib->thumbnails[i].xres,
&disclib->thumbnails[i].yres);
+                    disclib->thumbnails[i].path = (char *)s_temp;
+                    if (s_temp = xmlGetProp(cur_node, s_size)) {
+                        sscanf((const char*)s_temp, "%ix%i",
&disclib->thumbnails[i].xres, &disclib->thumbnails[i].yres);
+                        X_FREE(s_temp);
                     }
                     else {
                         disclib->thumbnails[i].xres =
disclib->thumbnails[i].yres = -1;
@@ -126,6 +145,20 @@ static void _findMetaXMLfiles(META_ROOT *meta,
const char *device_path)
 META_ROOT *meta_parse(const char *device_path)
 {
 #ifdef HAVE_LIBXML2
+   
+    s_title = xmlCharStrdup("title");
+    s_name = xmlCharStrdup("name");
+    s_alternative = xmlCharStrdup("alternative");
+    s_numSets = xmlCharStrdup("numSets");
+    s_setNumber = xmlCharStrdup("setNumber");
+    s_tableOfContents = xmlCharStrdup("tableOfContents");
+    s_titleName = xmlCharStrdup("titleName");
+    s_titleNumber = xmlCharStrdup("titleNumber");
+    s_description = xmlCharStrdup("description");
+    s_thumbnail = xmlCharStrdup("thumbnail");
+    s_href = xmlCharStrdup("href");
+    s_size = xmlCharStrdup("size");
+   
     META_ROOT *root = calloc(1, sizeof(META_ROOT));
     root->dl_count = 0;
 
@@ -142,6 +175,7 @@ META_ROOT *meta_parse(const char *device_path)
         BD_FILE_H *handle = file_open(path, "rb");
         if (handle == NULL) {
             BD_DEBUG(DBG_DIR, "Failed to open meta file (%s)\n", path);
+            X_FREE(path);
             continue;
         }
 
@@ -155,6 +189,8 @@ META_ROOT *meta_parse(const char *device_path)
             doc = xmlReadMemory((char*)data, size_read, base, NULL, 0);
             if (doc == NULL) {
                 BD_DEBUG(DBG_DIR, "Failed to parse %s\n", path);
+                X_FREE(base);
+                X_FREE(path);
                 continue;
             }
             xmlNode *root_element = NULL;
@@ -169,6 +205,8 @@ META_ROOT *meta_parse(const char *device_path)
             X_FREE(data);
         }
         file_close(handle);
+        X_FREE(base);
+        X_FREE(path);
     }
     xmlCleanupParser();
     return root;
@@ -214,18 +252,34 @@ void meta_free(META_ROOT **p)
         uint8_t i;
         for (i = 0; i < (*p)->dl_count; i++) {
             uint32_t t;
-            for (t=0; i < (*p)->dl_entries[i].toc_count; t++) {
+            for (t = 0; t < (*p)->dl_entries[i].toc_count; t++) {
                 X_FREE((*p)->dl_entries[i].toc_entries[t].title_name);
-                X_FREE((*p)->dl_entries[i].toc_entries);
             }
-            for (t = 0; i < (*p)->dl_entries[i].thumb_count; t++) {
+            for (t = 0; t < (*p)->dl_entries[i].thumb_count; t++) {
                 X_FREE((*p)->dl_entries[i].thumbnails[t].path);
-                X_FREE((*p)->dl_entries[i].thumbnails);
             }
+            X_FREE((*p)->dl_entries[i].toc_entries);
+            X_FREE((*p)->dl_entries[i].thumbnails);
             X_FREE((*p)->dl_entries[i].filename);
             X_FREE((*p)->dl_entries[i].di_name);
             X_FREE((*p)->dl_entries[i].di_alternative);
         }
+        X_FREE((*p)->dl_entries);
         X_FREE(*p);
     }
+   
+#ifdef HAVE_LIBXML2
+    X_FREE(s_title);
+    X_FREE(s_name);
+    X_FREE(s_alternative);
+    X_FREE(s_numSets);
+    X_FREE(s_setNumber);
+    X_FREE(s_tableOfContents);
+    X_FREE(s_titleName);
+    X_FREE(s_titleNumber);
+    X_FREE(s_description);
+    X_FREE(s_thumbnail);
+    X_FREE(s_href);
+    X_FREE(s_size);
+#endif
 }
diff --git a/src/libbluray/bluray.c b/src/libbluray/bluray.c
index 141a9b9..b25817e 100644
--- a/src/libbluray/bluray.c
+++ b/src/libbluray/bluray.c
@@ -1085,6 +1085,10 @@ void bd_close(BLURAY *bd)
     if (bd->title != NULL) {
         nav_title_close(bd->title);
     }
+   
+    if (bd->meta) {
+        meta_free(&bd->meta);
+    }
 
     hdmv_vm_free(&bd->hdmv_vm);
 
-- 
1.7.7



More information about the libbluray-devel mailing list