diff options
Diffstat (limited to 'backend/epub/epub-document.c')
-rw-r--r-- | backend/epub/epub-document.c | 112 |
1 files changed, 69 insertions, 43 deletions
diff --git a/backend/epub/epub-document.c b/backend/epub/epub-document.c index 52530f47..b63f91cb 100644 --- a/backend/epub/epub-document.c +++ b/backend/epub/epub-document.c @@ -31,9 +31,9 @@ #include <libxml/parser.h> #include <libxml/xmlmemory.h> #include <libxml/HTMLparser.h> -#include <config.h> -#include <glib/gi18n.h> +#include <config.h> +#include <glib/gi18n-lib.h> #include <glib/gstdio.h> #include <gtk/gtk.h> @@ -224,7 +224,6 @@ epub_document_links_has_document_links(EvDocumentLinks *document_links) return TRUE; } - typedef struct _LinksCBStruct { GtkTreeModel *model; GtkTreeIter *parent; @@ -413,7 +412,6 @@ epub_remove_temporary_dir (gchar *path_name) return (g_remove (path_name)); } - static gboolean check_mime_type (const gchar* uri, GError** error); @@ -625,45 +623,55 @@ xml_get_data_from_node(xmlNodePtr node, static gboolean check_mime_type(const gchar* uri,GError** error) { - GError * err = NULL ; - const gchar* mimeFromFile = ev_file_get_mime_type(uri,FALSE,&err); + GError * err = NULL; + const gchar* mimeFromFile; - gchar* mimetypes[] = {"application/epub+zip","application/x-booki+zip"}; - int typecount = 2; - if ( !mimeFromFile ) + mimeFromFile = ev_file_get_mime_type(uri, FALSE, &err); + if (mimeFromFile) { - if (err) { - g_propagate_error (error, err); + const gchar* mimetypes[] = {"application/epub+zip", "application/x-booki+zip", NULL}; + guint i; + + for (i = 0; mimetypes[i]; i++) { + if (strcmp(mimeFromFile, mimetypes[i]) == 0) + return TRUE; } - else { - g_set_error_literal (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("Unknown MIME Type")); + + /* fallback for malformed epub files */ + if (strcmp (mimeFromFile, "application/zip") == 0) + { + mimeFromFile = ev_file_get_mime_type (uri, TRUE, &err); + if (mimeFromFile) + { + for (i = 0; i < G_N_ELEMENTS (mimetypes); i++) { + if (g_strcmp0(mimeFromFile, mimetypes[i]) == 0) + return TRUE; + } + + /*We didn't find a match*/ + g_set_error_literal (error, + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_INVALID, + _("Not an ePub document")); + + return FALSE; + } } - return FALSE; } - else - { - int i=0; - for (i=0; i < typecount ;i++) { - if ( g_strcmp0(mimeFromFile, mimetypes[i]) == 0 ) { - return TRUE; - } - } - /*We didn't find a match*/ + if (err) + g_propagate_error (error, err); + else g_set_error_literal (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, - _("Not an ePub document")); + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_INVALID, + _("Unknown MIME Type")); - return FALSE; - } + return FALSE; } static gboolean -extract_one_file(EpubDocument* epub_document,GError ** error) +extract_one_file(EpubDocument* epub_document, GFile *tmp_gfile, GError ** error) { GFile * outfile ; gsize writesize = 0; @@ -690,6 +698,20 @@ extract_one_file(EpubDocument* epub_document,GError ** error) gfilepath = g_string_new(epub_document->tmp_archive_dir) ; g_string_append_printf(gfilepath,"/%s",(gchar*)currentfilename); + outfile = g_file_new_for_path (gfilepath->str); + g_autofree gchar *rpath = g_file_get_relative_path (tmp_gfile, outfile); + + if (rpath == NULL) + { + g_set_error_literal (error, + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_INVALID, + _("epub file is invalid or corrupt")); + g_critical ("Invalid filename in Epub container - '%s'", (gchar *) currentfilename); + result = FALSE; + goto out; + } + /*if we encounter a directory, make a directory inside our temporary folder.*/ if (directory != NULL && *directory == '\0') { @@ -717,7 +739,6 @@ extract_one_file(EpubDocument* epub_document,GError ** error) g_string_free(dir_create,TRUE); } - outfile = g_file_new_for_path(gfilepath->str); outstream = g_file_create(outfile,G_FILE_CREATE_PRIVATE,NULL,error); gpointer buffer = g_malloc0(512); while ( (writesize = unzReadCurrentFile(epub_document->epubDocument,buffer,512) ) != 0 ) @@ -730,10 +751,10 @@ extract_one_file(EpubDocument* epub_document,GError ** error) } g_free(buffer); g_output_stream_close((GOutputStream*)outstream,NULL,error); - g_object_unref(outfile) ; - g_object_unref(outstream) ; + g_object_unref(outstream); out: + g_object_unref(outfile); unzCloseCurrentFile (epub_document->epubDocument) ; g_string_free(gfilepath,TRUE); g_free(currentfilename); @@ -745,6 +766,7 @@ extract_epub_from_container (const gchar* uri, EpubDocument *epub_document, GError ** error) { + GFile *tmp_gfile = NULL; GError *err = NULL; epub_document->archivename = g_filename_from_uri(uri,NULL,error); @@ -806,9 +828,10 @@ extract_epub_from_container (const gchar* uri, goto out; } + tmp_gfile = g_file_new_for_path (epub_document->tmp_archive_dir); while ( TRUE ) { - if ( extract_one_file(epub_document,&err) == FALSE ) + if ( extract_one_file(epub_document, tmp_gfile, &err) == FALSE ) { if (err) { g_propagate_error (error, err); @@ -829,6 +852,7 @@ extract_epub_from_container (const gchar* uri, } out: + g_clear_object (&tmp_gfile); unzClose(epub_document->epubDocument); return result; } @@ -1020,7 +1044,7 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *docu } if ( xmlStrcmp(itemrefptr->name,(xmlChar*)"itemref") == 0) { - contentListNode *newnode = g_malloc0(sizeof(newnode)); + contentListNode *newnode = g_malloc0(sizeof(*newnode)); newnode->key = (gchar*)xml_get_data_from_node(itemrefptr,XML_ATTRIBUTE,(xmlChar*)"idref"); if ( newnode->key == NULL ) { @@ -1201,7 +1225,13 @@ setup_index_from_navfile(gchar *tocpath) GList *index = NULL; open_xml_document(tocpath); set_xml_root_node(NULL); - xmlNodePtr nav = xml_get_pointer_to_node((xmlChar*)"nav",(xmlChar*)"id",(xmlChar*)"toc"); + xmlNodePtr nav = xml_get_pointer_to_node((xmlChar*)"nav",(xmlChar*)"type",(xmlChar*)"toc"); + + if (nav == NULL) { + xml_free_doc(); + return NULL; + } + xmlretval=NULL; xml_parse_children_of_node(nav,(xmlChar*)"ol", NULL,NULL); gchar *navdirend = g_strrstr(tocpath,"/"); @@ -1546,7 +1576,6 @@ epub_document_check_add_night_sheet(EvDocument *document) gchar *csspath = g_strdup_printf("%s/atrilnightstyle.css",epub_document->documentdir); - GFile *styles = g_file_new_for_path (csspath); GOutputStream *outstream = (GOutputStream*)g_file_create(styles,G_FILE_CREATE_PRIVATE,NULL,NULL); if ( g_output_stream_write((GOutputStream*)outstream,style,strlen(style),NULL,NULL) == -1 ) @@ -1597,7 +1626,7 @@ page_set_function(linknode *Link, GList *contentList) contentListNode *pagedata; guint flag=0; - while (!flag) { + while (!flag && listiter) { pagedata = listiter->data; if (link_present_on_page(Link->pagelink, pagedata->value)) { flag=1; @@ -1620,7 +1649,6 @@ epub_document_set_index_pages(GList *index,GList *contentList) g_list_foreach(index,(GFunc)page_set_function,contentList); } - static void add_mathjax_script_node_to_file(gchar *filename, gchar *data) { @@ -1768,7 +1796,6 @@ epub_document_init (EpubDocument *epub_document) epub_document->docTitle = NULL; } - static void epub_document_finalize (GObject *object) { @@ -1810,7 +1837,6 @@ epub_document_finalize (GObject *object) G_OBJECT_CLASS (epub_document_parent_class)->finalize (object); } - static void epub_document_class_init (EpubDocumentClass *klass) { |