summaryrefslogtreecommitdiff
path: root/backend/epub/epub-document.c
diff options
context:
space:
mode:
Diffstat (limited to 'backend/epub/epub-document.c')
-rw-r--r--backend/epub/epub-document.c112
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)
{