[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