winemenubuilder: generate XML files using libxml2
Damjan Jovanovic
damjan.jov at gmail.com
Sat Nov 7 09:42:33 CST 2009
Changelog:
* generate XML files using libmxl2
Since libxml2 escapes XML special characters (eg. <, >, &) properly,
this should fix #13963.
Damjan Jovanovic
-------------- next part --------------
diff --git a/programs/winemenubuilder/Makefile.in b/programs/winemenubuilder/Makefile.in
index 092405e..9686a5d 100644
--- a/programs/winemenubuilder/Makefile.in
+++ b/programs/winemenubuilder/Makefile.in
@@ -6,7 +6,8 @@ VPATH = @srcdir@
MODULE = winemenubuilder.exe
APPMODE = -mwindows
IMPORTS = uuid shell32 shlwapi ole32 user32 advapi32 kernel32
-EXTRAINCL = @PNGINCL@
+EXTRAINCL = @PNGINCL@ @XML2INCL@
+EXTRALIBS = @XML2LIBS@
C_SRCS = \
winemenubuilder.c
diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index fb13878..bc319aa 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -102,6 +102,10 @@
#include <png.h>
#endif
+#ifdef HAVE_LIBXML2
+#include <libxml/xmlwriter.h>
+#endif
+
WINE_DEFAULT_DEBUG_CHANNEL(menubuilder);
#define in_desktop_dir(csidl) ((csidl)==CSIDL_DESKTOPDIRECTORY || \
@@ -919,6 +923,7 @@ static BOOL write_directory_entry(const char *directory, const char *location)
static BOOL write_menu_file(const char *unix_link, const char *filename)
{
+#ifdef HAVE_LIBXML2
char *tempfilename;
FILE *tempfile = NULL;
char *lastEntry;
@@ -926,6 +931,9 @@ static BOOL write_menu_file(const char *unix_link, const char *filename)
char *menuPath = NULL;
int i;
int count = 0;
+ xmlBufferPtr xmlBuffer = NULL;
+ xmlTextWriterPtr xmlWriter = NULL;
+ int rc;
BOOL ret = FALSE;
WINE_TRACE("(%s)\n", wine_dbgstr_a(filename));
@@ -954,10 +962,19 @@ static BOOL write_menu_file(const char *unix_link, const char *filename)
return FALSE;
}
- fprintf(tempfile, "<!DOCTYPE Menu PUBLIC \"-//freedesktop//DTD Menu 1.0//EN\"\n");
- fprintf(tempfile, "\"http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd\">\n");
- fprintf(tempfile, "<Menu>\n");
- fprintf(tempfile, " <Name>Applications</Name>\n");
+ xmlBuffer = xmlBufferCreate();
+ if (xmlBuffer == NULL)
+ goto end;
+ xmlWriter = xmlNewTextWriterMemory(xmlBuffer, 0);
+ if (xmlWriter == NULL)
+ goto end;
+
+ rc = xmlTextWriterWriteDTD(xmlWriter, BAD_CAST "Menu", BAD_CAST "-//freedesktop//DTD Menu 1.0//EN",
+ BAD_CAST "http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd", NULL);
+ if (rc >= 0)
+ rc = xmlTextWriterStartElement(xmlWriter, BAD_CAST "Menu");
+ if (rc >= 0)
+ rc = xmlTextWriterWriteElement(xmlWriter, BAD_CAST "Name", BAD_CAST "Applications");
name = HeapAlloc(GetProcessHeap(), 0, lstrlenA(filename) + 1);
if (name == NULL) goto end;
@@ -968,11 +985,26 @@ static BOOL write_menu_file(const char *unix_link, const char *filename)
if (filename[i] == '/')
{
char *dir_file_name;
+ char *wine_name;
+ char *wine_dir;
struct stat st;
name[i] = 0;
- fprintf(tempfile, " <Menu>\n");
- fprintf(tempfile, " <Name>%s%s</Name>\n", count ? "" : "wine-", name);
- fprintf(tempfile, " <Directory>%s%s.directory</Directory>\n", count ? "" : "wine-", name);
+ if (rc >= 0)
+ rc = xmlTextWriterStartElement(xmlWriter, BAD_CAST "Menu");
+ wine_name = heap_printf("%s%s", count ? "" : "wine-", name);
+ if (wine_name)
+ {
+ if (rc >= 0)
+ rc = xmlTextWriterWriteElement(xmlWriter, BAD_CAST "Name", BAD_CAST wine_name);
+ HeapFree(GetProcessHeap(), 0, wine_name);
+ }
+ wine_dir = heap_printf("%s%s.directory", count ? "" : "wine-", name);
+ if (wine_dir)
+ {
+ if (rc >= 0)
+ rc = xmlTextWriterWriteElement(xmlWriter, BAD_CAST "Directory", BAD_CAST wine_dir);
+ HeapFree(GetProcessHeap(), 0, wine_dir);
+ }
dir_file_name = heap_printf("%s/desktop-directories/%s%s.directory",
xdg_data_dir, count ? "" : "wine-", name);
if (dir_file_name)
@@ -988,12 +1020,20 @@ static BOOL write_menu_file(const char *unix_link, const char *filename)
}
name[i] = 0;
- fprintf(tempfile, " <Include>\n");
- fprintf(tempfile, " <Filename>%s</Filename>\n", name);
- fprintf(tempfile, " </Include>\n");
+ if (rc >= 0)
+ rc = xmlTextWriterStartElement(xmlWriter, BAD_CAST "Include");
+ if (rc >= 0)
+ rc = xmlTextWriterWriteElement(xmlWriter, BAD_CAST "Filename", BAD_CAST name);
+ if (rc >= 0)
+ rc = xmlTextWriterEndElement(xmlWriter); /* Include */
+
for (i = 0; i < count; i++)
- fprintf(tempfile, " </Menu>\n");
- fprintf(tempfile, "</Menu>\n");
+ {
+ if (rc >= 0)
+ rc = xmlTextWriterEndElement(xmlWriter); /* Menu */
+ }
+ if (rc >= 0)
+ rc = xmlTextWriterEndElement(xmlWriter); /* Menu */
menuPath = heap_printf("%s/%s", xdg_config_dir, name);
if (menuPath == NULL) goto end;
@@ -1001,8 +1041,14 @@ static BOOL write_menu_file(const char *unix_link, const char *filename)
ret = TRUE;
end:
+ if (xmlWriter)
+ xmlFreeTextWriter(xmlWriter);
+ if (ret && tempfile)
+ fprintf(tempfile, "%s", (const char *) xmlBuffer->content);
if (tempfile)
fclose(tempfile);
+ if (xmlBuffer)
+ xmlBufferFree(xmlBuffer);
if (ret)
ret = (rename(tempfilename, menuPath) == 0);
if (!ret && tempfilename)
@@ -1020,6 +1066,10 @@ end:
HeapFree(GetProcessHeap(), 0, name);
HeapFree(GetProcessHeap(), 0, menuPath);
return ret;
+#else
+ WINE_ERR("cannot generate menu file %s, libxml2 was not present at compile time\n", wine_dbgstr_a(filename));
+ return FALSE;
+#endif
}
static BOOL write_menu_entry(const char *unix_link, const char *link, const char *path, const char *args,
@@ -1791,28 +1841,55 @@ static BOOL cleanup_associations(void)
static BOOL write_freedesktop_mime_type_entry(const char *packages_dir, const char *dot_extension,
const char *mime_type, const char *comment)
{
+#ifdef HAVE_LIBXML2
BOOL ret = FALSE;
char *filename;
WINE_TRACE("writing MIME type %s, extension=%s, comment=%s\n", wine_dbgstr_a(mime_type),
wine_dbgstr_a(dot_extension), wine_dbgstr_a(comment));
- filename = heap_printf("%s/x-wine-extension-%s.xml", packages_dir, &dot_extension[1]);
+ filename = heap_printf("file://%s/x-wine-extension-%s.xml", packages_dir, &dot_extension[1]);
if (filename)
{
- FILE *packageFile = fopen(filename, "w");
- if (packageFile)
+ xmlTextWriterPtr writer;
+ int rc;
+ writer = xmlNewTextWriterFilename(filename, 0);
+ if (writer)
{
- fprintf(packageFile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- fprintf(packageFile, "<mime-info xmlns=\"http://www.freedesktop.org/standards/shared-mime-info\">\n");
- fprintf(packageFile, " <mime-type type=\"%s\">\n", mime_type);
- fprintf(packageFile, " <glob pattern=\"*%s\"/>\n", dot_extension);
- if (comment)
- fprintf(packageFile, " <comment>%s</comment>\n", comment);
- fprintf(packageFile, " </mime-type>\n");
- fprintf(packageFile, "</mime-info>\n");
- ret = TRUE;
- fclose(packageFile);
+ rc = xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL);
+ if (rc >= 0)
+ rc = xmlTextWriterStartElement(writer, BAD_CAST "mime-info");
+ if (rc >= 0)
+ rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "xmlns",
+ BAD_CAST "http://www.freedesktop.org/standards/shared-mime-info");
+ if (rc >= 0)
+ rc = xmlTextWriterStartElement(writer, BAD_CAST "mime-type");
+ if (rc >= 0)
+ rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST mime_type);
+ if (rc >= 0)
+ rc = xmlTextWriterStartElement(writer, BAD_CAST "glob");
+ if (rc >= 0)
+ {
+ char *star_dot_extension = heap_printf("*%s", dot_extension);
+ if (star_dot_extension)
+ {
+ rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pattern", BAD_CAST star_dot_extension);
+ HeapFree(GetProcessHeap(), 0, star_dot_extension);
+ }
+ else
+ rc = -1;
+ }
+ if (rc >= 0)
+ rc = xmlTextWriterEndElement(writer); /* glob */
+ if (rc >= 0 && comment)
+ rc = xmlTextWriterWriteElement(writer, BAD_CAST "comment", BAD_CAST comment);
+ if (rc >= 0)
+ rc = xmlTextWriterEndElement(writer); /* mime-type */
+ if (rc >= 0)
+ rc = xmlTextWriterEndElement(writer); /* mime-info */
+
+ ret = (rc >= 0);
+ xmlFreeTextWriter(writer);
}
else
WINE_ERR("error writing file %s\n", filename);
@@ -1821,6 +1898,11 @@ static BOOL write_freedesktop_mime_type_entry(const char *packages_dir, const ch
else
WINE_ERR("out of memory\n");
return ret;
+#else
+ WINE_ERR("cannot generate MIME type entry for extension %s, libxml2 was not present at compile time\n",
+ wine_dbgstr_a(dot_extension));
+ return FALSE;
+#endif
}
static BOOL is_extension_blacklisted(LPCWSTR extension)
More information about the wine-patches
mailing list