diff --git a/CVE-2023-51698.patch b/CVE-2023-51698.patch deleted file mode 100644 index 71093514f4a131afdafd9714732463af248163d9..0000000000000000000000000000000000000000 --- a/CVE-2023-51698.patch +++ /dev/null @@ -1,1843 +0,0 @@ -From 71c3efaf1e42e6ba87f5385c5524ad403dd864d2 Mon Sep 17 00:00:00 2001 -From: peijiankang -Date: Wed, 24 Apr 2024 11:34:50 +0800 -Subject: [PATCH] CVE-2023-51698 - ---- - backend/comics/Makefile.am | 5 +- - backend/comics/comics-document.c | 1158 +++++++++++------------------- - backend/comics/comics-document.h | 9 +- - backend/comics/ev-archive.c | 323 +++++++++ - backend/comics/ev-archive.h | 56 ++ - configure.ac | 3 + - libdocument/ev-document.h | 1 + - 7 files changed, 806 insertions(+), 749 deletions(-) - create mode 100644 backend/comics/ev-archive.c - create mode 100644 backend/comics/ev-archive.h - -diff --git a/backend/comics/Makefile.am b/backend/comics/Makefile.am -index 99ef5f4..519cb49 100644 ---- a/backend/comics/Makefile.am -+++ b/backend/comics/Makefile.am -@@ -12,12 +12,15 @@ backend_LTLIBRARIES = libcomicsdocument.la - - libcomicsdocument_la_SOURCES = \ - comics-document.c \ -- comics-document.h -+ comics-document.h \ -+ ev-archive.c \ -+ ev-archive.h - - libcomicsdocument_la_LDFLAGS = $(BACKEND_LIBTOOL_FLAGS) - libcomicsdocument_la_LIBADD = \ - $(top_builddir)/libdocument/libatrildocument.la \ - $(BACKEND_LIBS) \ -+ $(COMICS_LIBS) \ - $(LIB_LIBS) - - backend_in_files = comicsdocument.atril-backend.in -diff --git a/backend/comics/comics-document.c b/backend/comics/comics-document.c -index 4d4d293..1da1eee 100644 ---- a/backend/comics/comics-document.c -+++ b/backend/comics/comics-document.c -@@ -30,24 +30,17 @@ - #include - #include - --#include -- - #include "comics-document.h" - #include "ev-document-misc.h" - #include "ev-document-thumbnails.h" - #include "ev-file-helpers.h" -+#include "ev-archive.h" -+#include -+#include - - #define EV_EOL "\n" - --typedef enum --{ -- RARLABS, -- GNAUNRAR, -- UNZIP, -- P7ZIP, -- TAR, -- UNARCHIVER --} ComicBookDecompressType; -+#define BLOCK_SIZE 10240 - - typedef struct _ComicsDocumentClass ComicsDocumentClass; - -@@ -58,400 +51,269 @@ struct _ComicsDocumentClass - - struct _ComicsDocument - { -- EvDocument parent_instance; -- -- gchar *archive, *dir; -- GPtrArray *page_names; -- gchar *selected_command, *alternative_command; -- gchar *extract_command, *list_command, *decompress_tmp; -- gboolean regex_arg; -- gint offset; -- ComicBookDecompressType command_usage; -+ EvDocument parent_instance; -+ EvArchive *archive; -+ gchar *archive_path; -+ gchar *archive_uri; -+ GPtrArray *page_names; /* elem: char * */ -+ GHashTable *page_positions; /* key: char *, value: uint + 1 */ -+ - }; - --#define OFFSET_7Z 53 --#define OFFSET_ZIP 2 --#define NO_OFFSET 0 -- --/* For perfomance reasons of 7z* we've choosen to decompress on the temporary -- * directory instead of decompressing on the stdout */ -- --/** -- * @extract: command line arguments to pass to extract a file from the archive -- * to stdout. -- * @list: command line arguments to list the archive contents -- * @decompress_tmp: command line arguments to pass to extract the archive -- * into a directory. -- * @regex_arg: whether the command can accept regex expressions -- * @offset: the position offset of the filename on each line in the output of -- * running the @list command -- */ --typedef struct { -- char *extract; -- char *list; -- char *decompress_tmp; -- gboolean regex_arg; -- gint offset; --} ComicBookDecompressCommand; -+static void -+comics_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface); -+EV_BACKEND_REGISTER_WITH_CODE (ComicsDocument, comics_document, -+ { -+ EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS, -+ comics_document_document_thumbnails_iface_init); -+ } ); -+ -+#define FORMAT_UNKNOWN 0 -+#define FORMAT_SUPPORTED 1 -+#define FORMAT_UNSUPPORTED 2 -+ -+/* Returns a GHashTable of: -+ * : file extensions -+ * : degree of support in gdk-pixbuf */ -+static GHashTable * -+get_image_extensions(void) -+{ -+ GHashTable *extensions; -+ GSList *formats = gdk_pixbuf_get_formats (); -+ GSList *l; -+ guint i; -+ const char *known_image_formats[] = { -+ "png", -+ "jpg", -+ "jpeg", -+ "webp" -+ }; -+ -+ extensions = g_hash_table_new_full (g_str_hash, g_str_equal, -+ g_free, NULL); -+ for (l = formats; l != NULL; l = l->next) { -+ int i; -+ gchar **ext = gdk_pixbuf_format_get_extensions (l->data); - --static const ComicBookDecompressCommand command_usage_def[] = { -- /* RARLABS unrar */ -- {"%s p -c- -ierr --", "%s vb -c- -- %s", NULL , FALSE, NO_OFFSET}, -+ for (i = 0; ext[i] != NULL; i++) { -+ g_hash_table_insert (extensions, -+ g_strdup (ext[i]), -+ GINT_TO_POINTER (FORMAT_SUPPORTED)); -+ } - -- /* GNA! unrar */ -- {NULL , "%s t %s" , "%s -xf %s %s" , FALSE, NO_OFFSET}, -+ g_strfreev (ext); -+ } -+ g_slist_free (formats); - -- /* unzip */ -- {"%s -p -C --" , "%s %s" , NULL , TRUE , OFFSET_ZIP}, -+ /* Add known image formats that aren't supported by gdk-pixbuf */ -+ for (i = 0; i < G_N_ELEMENTS (known_image_formats); i++) { -+ if (!g_hash_table_lookup (extensions, known_image_formats[i])) { -+ g_hash_table_insert (extensions, -+ g_strdup (known_image_formats[i]), -+ GINT_TO_POINTER (FORMAT_UNSUPPORTED)); -+ } -+ } - -- /* 7zip */ -- {NULL , "%s l -- %s" , "%s x -y %s -o%s", FALSE, OFFSET_7Z}, -+ return extensions; -+} - -- /* tar */ -- {"%s -xOf" , "%s -tf %s" , NULL , FALSE, NO_OFFSET}, -+static int -+has_supported_extension (const char *name, -+ GHashTable *supported_extensions) -+{ -+ gboolean ret = FALSE; -+ gchar *suffix; -+ suffix = g_strrstr (name, "."); -+ if (!suffix) -+ return ret; - -- /* UNARCHIVER */ -- {"unar -o -" , "%s %s" , NULL , FALSE, NO_OFFSET} --}; -+ suffix = g_ascii_strdown (suffix + 1, -1); -+ ret = GPOINTER_TO_INT (g_hash_table_lookup (supported_extensions, suffix)); -+ g_free (suffix); - --static void comics_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface); -+ return ret; -+} - --static GSList* get_supported_image_extensions (void); --static void get_page_size_area_prepared_cb (GdkPixbufLoader *loader, -- gpointer data); --static void render_pixbuf_size_prepared_cb (GdkPixbufLoader *loader, -- gint width, -- gint height, -- gpointer data); --static char** extract_argv (EvDocument *document, -- gint page); -+#define APPLE_DOUBLE_PREFIX "._" -+static gboolean -+is_apple_double (const char *name) -+{ -+char *basename; -+ gboolean ret = FALSE; - -+ basename = g_path_get_basename (name); -+ if (basename == NULL) { -+ g_debug ("Filename '%s' doesn't have a basename?", name); -+ return ret; -+ } -+ ret = g_str_has_prefix (basename, APPLE_DOUBLE_PREFIX); -+ g_free (basename); - --EV_BACKEND_REGISTER_WITH_CODE (ComicsDocument, comics_document, -- { -- EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS, -- comics_document_document_thumbnails_iface_init); -- } ); -- --/** -- * comics_regex_quote: -- * @unquoted_string: a literal string -- * -- * Quotes a string so unzip will not interpret the regex expressions of -- * @unquoted_string. Basically, this functions uses [] to disable regex -- * expressions. The return value must be freed with * g_free() -- * -- * Return value: quoted and disabled-regex string -- **/ --static gchar * --comics_regex_quote (const gchar *unquoted_string) -+ return ret; -+} -+ -+static gboolean -+archive_reopen_if_needed (ComicsDocument *comics_document, -+ const char *page_wanted, -+ GError **error) - { -- const gchar *p; -- GString *dest; -- -- dest = g_string_new ("'"); -- -- p = unquoted_string; -- -- while (*p) { -- switch (*p) { -- /* * matches a sequence of 0 or more characters */ -- case ('*'): -- /* ? matches exactly 1 charactere */ -- case ('?'): -- /* [...] matches any single character found inside -- * the brackets. Disabling the first bracket is enough. -- */ -- case ('['): -- g_string_append (dest, "["); -- g_string_append_c (dest, *p); -- g_string_append (dest, "]"); -- break; -- /* Because \ escapes regex expressions that we are -- * disabling for unzip, we need to disable \ too */ -- case ('\\'): -- g_string_append (dest, "[\\\\]"); -- break; -- /* Escape single quote inside the string */ -- case ('\''): -- g_string_append (dest, "'\\''"); -- break; -- default: -- g_string_append_c (dest, *p); -- break; -+ const char *current_page; -+ guint current_page_idx, page_wanted_idx; -+ -+ if (ev_archive_at_entry (comics_document->archive)) { -+ current_page = ev_archive_get_entry_pathname (comics_document->archive); -+ if (current_page) { -+ current_page_idx = GPOINTER_TO_UINT (g_hash_table_lookup (comics_document->page_positions, current_page)); -+ page_wanted_idx = GPOINTER_TO_UINT (g_hash_table_lookup (comics_document->page_positions, page_wanted)); -+ -+ if (current_page_idx != 0 && -+ page_wanted_idx != 0 && -+ page_wanted_idx > current_page_idx) -+ return TRUE; - } -- ++p; -+ -+ ev_archive_reset (comics_document->archive); - } -- g_string_append_c (dest, '\''); -- return g_string_free (dest, FALSE); -+return ev_archive_open_filename (comics_document->archive, comics_document->archive_path, error); - } - -- --/* This function manages the command for decompressing a comic book */ --static gboolean --comics_decompress_temp_dir (const gchar *command_decompress_tmp, -- const gchar *command, -- GError **error) -+static GPtrArray * -+comics_document_list (ComicsDocument *comics_document, -+ GError **error) - { -- gboolean success; -- gchar *std_out, *basename; -- GError *err = NULL; -- gint retval; -- -- success = g_spawn_command_line_sync (command_decompress_tmp, &std_out, -- NULL, &retval, &err); -- basename = g_path_get_basename (command); -- if (!success) { -- g_set_error (error, -- EV_DOCUMENT_ERROR, -- EV_DOCUMENT_ERROR_INVALID, -- _("Error launching the command “%s” in order to " -- "decompress the comic book: %s"), -- basename, -- err->message); -- g_error_free (err); -- } else if (WIFEXITED (retval)) { -- if (WEXITSTATUS (retval) == EXIT_SUCCESS) { -- g_free (std_out); -- g_free (basename); -- return TRUE; -- } else { -- g_set_error (error, -+GPtrArray *array = NULL; -+ gboolean has_encrypted_files, has_unsupported_images, has_archive_errors; -+ GHashTable *supported_extensions = NULL; -+ -+ if (!ev_archive_open_filename (comics_document->archive, comics_document->archive_path, error)) { -+ if (*error != NULL) { -+ g_warning ("Fatal error handling archive (%s): %s", G_STRFUNC, (*error)->message); -+ g_clear_error (error); -+ } -+ -+ g_set_error_literal (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, -- _("The command “%s” failed at " -- "decompressing the comic book."), -- basename); -- g_free (std_out); -+ _("File is corrupted")); -+ goto out; -+ } -+ -+ supported_extensions = get_image_extensions (); -+ -+ has_encrypted_files = FALSE; -+ has_unsupported_images = FALSE; -+ has_archive_errors = FALSE; -+ array = g_ptr_array_sized_new (64); -+ -+ while (1) { -+ const char *name; -+ int supported; -+ -+ if (!ev_archive_read_next_header (comics_document->archive, error)) { -+ if (*error != NULL) { -+ g_debug ("Fatal error handling archive (%s): %s", G_STRFUNC, (*error)->message); -+ g_clear_error (error); -+ has_archive_errors = TRUE; -+ goto out; -+ } -+ break; - } -- } else { -- g_set_error (error, -- EV_DOCUMENT_ERROR, -- EV_DOCUMENT_ERROR_INVALID, -- _("The command “%s” did not end normally."), -- basename); -- g_free (std_out); -+ -+ name = ev_archive_get_entry_pathname (comics_document->archive); -+ /* Ignore https://en.wikipedia.org/wiki/AppleSingle_and_AppleDouble_formats */ -+ if (is_apple_double (name)) { -+ g_debug ("Not adding AppleDouble file '%s' to the list of files in the comics", name); -+ continue; -+ } -+ -+ supported = has_supported_extension (name, supported_extensions); -+ if (supported == FORMAT_UNKNOWN) { -+ g_debug ("Not adding unsupported file '%s' to the list of files in the comics", name); -+ continue; -+ } else if (supported == FORMAT_UNSUPPORTED) { -+ g_debug ("Not adding unsupported image '%s' to the list of files in the comics", name); -+ has_unsupported_images = TRUE; -+ continue; -+ } -+ -+ if (ev_archive_get_entry_is_encrypted (comics_document->archive)) { -+ g_debug ("Not adding encrypted file '%s' to the list of files in the comics", name); -+ has_encrypted_files = TRUE; -+ continue; -+ } -+ -+ g_debug ("Adding '%s' to the list of files in the comics", name); -+ g_ptr_array_add (array, g_strdup (name)); - } -- g_free (basename); -- return FALSE; -+out: -+ if (array->len == 0) { -+ g_ptr_array_free (array, TRUE); -+ array = NULL; -+ -+ if (has_encrypted_files) { -+ g_set_error_literal (error, -+ EV_DOCUMENT_ERROR, -+ EV_DOCUMENT_ERROR_ENCRYPTED, -+ _("Archive is encrypted")); -+ } else if (has_unsupported_images) { -+ g_set_error_literal (error, -+ EV_DOCUMENT_ERROR, -+ EV_DOCUMENT_ERROR_UNSUPPORTED_CONTENT, -+ _("No supported images in archive")); -+ } else if (has_archive_errors) { -+ g_set_error_literal (error, -+ EV_DOCUMENT_ERROR, -+ EV_DOCUMENT_ERROR_INVALID, -+ _("File is corrupted")); -+ } else { -+ g_set_error_literal (error, -+ EV_DOCUMENT_ERROR, -+ EV_DOCUMENT_ERROR_INVALID, -+ _("No files in archive")); -+ } -+ } -+ -+ if (supported_extensions) -+ g_hash_table_destroy (supported_extensions); -+ ev_archive_reset (comics_document->archive); -+ return array; - } - --/* This function shows how to use the choosen command for decompressing a -- * comic book file. It modifies fields of the ComicsDocument struct with -- * this information */ --static gboolean --comics_generate_command_lines (ComicsDocument *comics_document, -- GError **error) -+static GHashTable * -+save_positions (GPtrArray *page_names) - { -- gchar *quoted_file, *quoted_file_aux; -- gchar *quoted_command; -- ComicBookDecompressType type; -- -- type = comics_document->command_usage; -- comics_document->regex_arg = command_usage_def[type].regex_arg; -- quoted_command = g_shell_quote (comics_document->selected_command); -- if (comics_document->regex_arg) { -- quoted_file = comics_regex_quote (comics_document->archive); -- quoted_file_aux = g_shell_quote (comics_document->archive); -- comics_document->list_command = -- g_strdup_printf (command_usage_def[type].list, -- comics_document->alternative_command, -- quoted_file_aux); -- g_free (quoted_file_aux); -- } else { -- quoted_file = g_shell_quote (comics_document->archive); -- comics_document->list_command = -- g_strdup_printf (command_usage_def[type].list, -- quoted_command, quoted_file); -- } -- comics_document->extract_command = -- g_strdup_printf (command_usage_def[type].extract, -- quoted_command); -- comics_document->offset = command_usage_def[type].offset; -- if (command_usage_def[type].decompress_tmp) { -- comics_document->dir = ev_mkdtemp ("atril-comics-XXXXXX", error); -- if (comics_document->dir == NULL) -- return FALSE; -- -- /* unrar-free can't create directories, but ev_mkdtemp already created the dir */ -- -- comics_document->decompress_tmp = -- g_strdup_printf (command_usage_def[type].decompress_tmp, -- quoted_command, quoted_file, -- comics_document->dir); -- g_free (quoted_file); -- g_free (quoted_command); -- -- if (!comics_decompress_temp_dir (comics_document->decompress_tmp, -- comics_document->selected_command, error)) -- return FALSE; -- else -- return TRUE; -- } else { -- g_free (quoted_file); -- g_free (quoted_command); -- return TRUE; -- } -+ guint i; -+ GHashTable *ht; - -+ ht = g_hash_table_new (g_str_hash, g_str_equal); -+ for (i = 0; i < page_names->len; i++) -+ g_hash_table_insert (ht, page_names->pdata[i], GUINT_TO_POINTER(i + 1)); -+ return ht; - } - --/* This function chooses an external command for decompressing a comic -- * book based on its mime tipe. */ --static gboolean --comics_check_decompress_command (gchar *mime_type, -+/*This function chooses the archive decompression support -+ * book based on its mime type. */ -+static gboolean -+comics_check_decompress_support (gchar *mime_type, - ComicsDocument *comics_document, - GError **error) - { -- gboolean success; -- gchar *std_out, *std_err; -- gint retval; -- GError *err = NULL; -- -- /* FIXME, use proper cbr/cbz mime types once they're -- * included in shared-mime-info */ -- - if (g_content_type_is_a (mime_type, "application/x-cbr") || - g_content_type_is_a (mime_type, "application/x-rar")) { -- /* The RARLAB provides a no-charge proprietary (freeware) -- * decompress-only client for Linux called unrar. Another -- * option is a GPLv2-licensed command-line tool developed by -- * the Gna! project. Confusingly enough, the free software RAR -- * decoder is also named unrar. For this reason we need to add -- * some lines for disambiguation. Sorry for the added the -- * complexity but it's life :) -- * Finally, some distributions, like Debian, rename this free -- * option as unrar-free. -- * */ -- comics_document->selected_command = -- g_find_program_in_path ("unrar"); -- if (comics_document->selected_command) { -- /* We only use std_err to avoid printing useless error -- * messages on the terminal */ -- success = -- g_spawn_command_line_sync ( -- comics_document->selected_command, -- &std_out, &std_err, -- &retval, &err); -- if (!success) { -- g_propagate_error (error, err); -- g_error_free (err); -- return FALSE; -- /* I don't check retval status because RARLAB unrar -- * doesn't have a way to return 0 without involving an -- * operation with a file*/ -- } else if (WIFEXITED (retval)) { -- if (g_strrstr (std_out,"freeware") != NULL) -- /* The RARLAB freeware client */ -- comics_document->command_usage = RARLABS; -- else -- /* The Gna! free software client */ -- comics_document->command_usage = GNAUNRAR; -- -- g_free (std_out); -- g_free (std_err); -- return TRUE; -- } -- } -- /* The Gna! free software client with Debian naming convention */ -- comics_document->selected_command = -- g_find_program_in_path ("unrar-free"); -- if (comics_document->selected_command) { -- comics_document->command_usage = GNAUNRAR; -- return TRUE; -- } -- comics_document->selected_command = -- g_find_program_in_path ("lsar"); -- if (comics_document->selected_command) { -- comics_document->command_usage = UNARCHIVER; -+ if (ev_archive_set_archive_type (comics_document->archive, EV_ARCHIVE_TYPE_RAR)) - return TRUE; -- } -- comics_document->selected_command = -- g_find_program_in_path ("bsdtar"); -- if (comics_document->selected_command) { -- comics_document->command_usage = TAR; -- return TRUE; -- } -- - } else if (g_content_type_is_a (mime_type, "application/x-cbz") || - g_content_type_is_a (mime_type, "application/zip")) { -- /* InfoZIP's unzip program */ -- comics_document->selected_command = -- g_find_program_in_path ("unzip"); -- comics_document->alternative_command = -- g_find_program_in_path ("zipnote"); -- if (comics_document->selected_command && -- comics_document->alternative_command) { -- comics_document->command_usage = UNZIP; -+ if (ev_archive_set_archive_type (comics_document->archive, EV_ARCHIVE_TYPE_ZIP)) - return TRUE; -- } -- comics_document->selected_command = -- g_find_program_in_path ("bsdtar"); -- if (comics_document->selected_command) { -- comics_document->command_usage = TAR; -- return TRUE; -- } -- comics_document->selected_command = -- g_find_program_in_path ("lsar"); -- if (comics_document->selected_command) { -- comics_document->command_usage = UNARCHIVER; -- return TRUE; -- } -- - } else if (g_content_type_is_a (mime_type, "application/x-cb7") || - g_content_type_is_a (mime_type, "application/x-7z-compressed")) { -- /* 7zr, 7za and 7z are the commands from the p7zip project able -- * to decompress .7z files */ -- comics_document->selected_command = -- g_find_program_in_path ("7zr"); -- if (comics_document->selected_command) { -- comics_document->command_usage = P7ZIP; -- return TRUE; -- } -- comics_document->selected_command = -- g_find_program_in_path ("7za"); -- if (comics_document->selected_command) { -- comics_document->command_usage = P7ZIP; -+ if (ev_archive_set_archive_type (comics_document->archive, EV_ARCHIVE_TYPE_7Z)) - return TRUE; -- } -- comics_document->selected_command = -- g_find_program_in_path ("7z"); -- if (comics_document->selected_command) { -- comics_document->command_usage = P7ZIP; -- return TRUE; -- } -- comics_document->selected_command = -- g_find_program_in_path ("bsdtar"); -- if (comics_document->selected_command) { -- comics_document->command_usage = TAR; -- return TRUE; -- } -- comics_document->selected_command = -- g_find_program_in_path ("lsar"); -- if (comics_document->selected_command) { -- comics_document->command_usage = UNARCHIVER; -- return TRUE; -- } - } else if (g_content_type_is_a (mime_type, "application/x-cbt") || - g_content_type_is_a (mime_type, "application/x-tar")) { -- /* tar utility (Tape ARchive) */ -- comics_document->selected_command = -- g_find_program_in_path ("tar"); -- if (comics_document->selected_command) { -- comics_document->command_usage = TAR; -- return TRUE; -- } -- comics_document->selected_command = -- g_find_program_in_path ("bsdtar"); -- if (comics_document->selected_command) { -- comics_document->command_usage = TAR; -+ if (ev_archive_set_archive_type (comics_document->archive, EV_ARCHIVE_TYPE_TAR)) - return TRUE; -- } -- comics_document->selected_command = -- g_find_program_in_path ("lsar"); -- if (comics_document->selected_command) { -- comics_document->command_usage = UNARCHIVER; -- return TRUE; -- } - } else { - g_set_error (error, - EV_DOCUMENT_ERROR, -@@ -463,8 +325,9 @@ comics_check_decompress_command (gchar *mime_type, - g_set_error_literal (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, -- _("Can't find an appropriate command to " -- "decompress this type of comic book")); -+ _("libarchive lacks support for this comic book’s " -+ "compression, please contact your distributor")); -+ - return FALSE; - } - -@@ -472,43 +335,15 @@ static int - sort_page_names (gconstpointer a, - gconstpointer b) - { -- const char *name_1, *name_2; -- gchar *key_1, *key_2; -- gboolean sort_last_1, sort_last_2; -- int compare; -- -- name_1 = * (const char **) a; -- name_2 = * (const char **) b; -- -- #define SORT_LAST_CHAR1 '.' -- #define SORT_LAST_CHAR2 '#' -- -- sort_last_1 = name_1[0] == SORT_LAST_CHAR1 || name_1[0] == SORT_LAST_CHAR2; -- sort_last_2 = name_2[0] == SORT_LAST_CHAR1 || name_2[0] == SORT_LAST_CHAR2; -- -- #undef SORT_LAST_CHAR1 -- #undef SORT_LAST_CHAR2 -- -- if (sort_last_1 && !sort_last_2) -- { -- compare = +1; -- } -- else if (!sort_last_1 && sort_last_2) -- { -- compare = -1; -- } -- else -- { -- key_1 = g_utf8_collate_key_for_filename (name_1, -1); -- key_2 = g_utf8_collate_key_for_filename (name_2, -1); -- -- compare = strcmp (key_1, key_2); -- -- g_free (key_1); -- g_free (key_2); -- } -- -- return compare; -+ gchar *temp1, *temp2; -+ gint ret; -+ temp1 = g_utf8_collate_key_for_filename (* (const char **) a, -1); -+ temp2 = g_utf8_collate_key_for_filename (* (const char **) b, -1); -+ ret = strcmp (temp1, temp2); -+ -+ g_free (temp1); -+ g_free (temp2); -+ return ret; - } - - static gboolean -@@ -517,50 +352,13 @@ comics_document_load (EvDocument *document, - GError **error) - { - ComicsDocument *comics_document = COMICS_DOCUMENT (document); -- GSList *supported_extensions; -- gchar *std_out; - gchar *mime_type; -- gchar **cb_files, *cb_file; -- gboolean success; -- int i, retval; -- GError *err = NULL; -- -- comics_document->archive = g_filename_from_uri (uri, NULL, error); -- if (!comics_document->archive) -- return FALSE; -- -- mime_type = ev_file_get_mime_type (uri, FALSE, &err); -- if (!mime_type) { -- if (err) { -- g_propagate_error (error, err); -- } else { -- g_set_error_literal (error, -- EV_DOCUMENT_ERROR, -- EV_DOCUMENT_ERROR_INVALID, -- _("Unknown MIME Type")); -- } -+ GFile *file; -+ file = g_file_new_for_uri (uri); -+ comics_document->archive_path = g_file_get_path (file); -+ g_object_unref (file); - -- return FALSE; -- } -- -- if (!comics_check_decompress_command (mime_type, comics_document, -- error)) { -- g_free (mime_type); -- return FALSE; -- } else if (!comics_generate_command_lines (comics_document, error)) { -- g_free (mime_type); -- return FALSE; -- } -- -- g_free (mime_type); -- -- /* Get list of files in archive */ -- success = g_spawn_command_line_sync (comics_document->list_command, -- &std_out, NULL, &retval, error); -- -- if (!success) { -- return FALSE; -- } else if (!WIFEXITED(retval) || WEXITSTATUS(retval) != EXIT_SUCCESS) { -+ if (!comics_document->archive_path) { - g_set_error_literal (error, - EV_DOCUMENT_ERROR, - EV_DOCUMENT_ERROR_INVALID, -@@ -568,58 +366,26 @@ comics_document_load (EvDocument *document, - return FALSE; - } - -- /* FIXME: is this safe against filenames containing \n in the archive ? */ -- cb_files = g_strsplit (std_out, EV_EOL, 0); -+ comics_document->archive_uri = g_strdup (uri); -+ mime_type = ev_file_get_mime_type (uri, FALSE, error); - -- g_free (std_out); -+ if (mime_type == NULL) -+ return FALSE; - -- if (!cb_files) { -- g_set_error_literal (error, -- EV_DOCUMENT_ERROR, -- EV_DOCUMENT_ERROR_INVALID, -- _("No files in archive")); -+ if (!comics_check_decompress_support (mime_type, comics_document, error)) { -+ g_free (mime_type); - return FALSE; - } - -- comics_document->page_names = g_ptr_array_sized_new (64); -- -- supported_extensions = get_supported_image_extensions (); -- for (i = 0; cb_files[i] != NULL; i++) { -- if (comics_document->offset != NO_OFFSET) { -- if (g_utf8_strlen (cb_files[i],-1) > -- comics_document->offset) { -- cb_file = -- g_utf8_offset_to_pointer (cb_files[i], -- comics_document->offset); -- } else { -- continue; -- } -- } else { -- cb_file = cb_files[i]; -- } -- gchar *suffix = g_strrstr (cb_file, "."); -- if (!suffix) -- continue; -- suffix = g_ascii_strdown (suffix + 1, -1); -- if (g_slist_find_custom (supported_extensions, suffix, -- (GCompareFunc) strcmp) != NULL) { -- g_ptr_array_add (comics_document->page_names, -- g_strstrip (g_strdup (cb_file))); -- } -- g_free (suffix); -- } -- g_strfreev (cb_files); -- g_slist_foreach (supported_extensions, (GFunc) g_free, NULL); -- g_slist_free (supported_extensions); -+ g_free (mime_type); - -- if (comics_document->page_names->len == 0) { -- g_set_error (error, -- EV_DOCUMENT_ERROR, -- EV_DOCUMENT_ERROR_INVALID, -- _("No images found in archive %s"), -- uri); -+ /* Get list of files in archive */ -+ comics_document->page_names = comics_document_list (comics_document, error); -+ if (!comics_document->page_names) - return FALSE; -- } -+ -+ /* Keep an index */ -+ comics_document->page_positions = save_positions (comics_document->page_names); - - /* Now sort the pages */ - g_ptr_array_sort (comics_document->page_names, sort_page_names); -@@ -627,7 +393,6 @@ comics_document_load (EvDocument *document, - return TRUE; - } - -- - static gboolean - comics_document_save (EvDocument *document, - const char *uri, -@@ -635,7 +400,7 @@ comics_document_save (EvDocument *document, - { - ComicsDocument *comics_document = COMICS_DOCUMENT (document); - -- return ev_xfer_uri_simple (comics_document->archive, uri, error); -+ return ev_xfer_uri_simple (comics_document->archive_uri, uri, error); - } - - static int -@@ -649,6 +414,23 @@ comics_document_get_n_pages (EvDocument *document) - return comics_document->page_names->len; - } - -+typedef struct { -+ gboolean got_info; -+ int height; -+ int width; -+} PixbufInfo; -+ -+static void -+get_page_size_prepared_cb (GdkPixbufLoader *loader, -+ int width, -+ int height, -+ PixbufInfo *info) -+{ -+ info->got_info = TRUE; -+ info->height = height; -+ info->width = width; -+} -+ - static void - comics_document_get_page_size (EvDocument *document, - EvPage *page, -@@ -656,74 +438,89 @@ comics_document_get_page_size (EvDocument *document, - double *height) - { - GdkPixbufLoader *loader; -- char **argv; -- guchar buf[1024]; -- gboolean success, got_size = FALSE; -- gint outpipe = -1; -- GPid child_pid; -- gssize bytes; -- GdkPixbuf *pixbuf; -- gchar *filename; -+ - ComicsDocument *comics_document = COMICS_DOCUMENT (document); -- -- if (!comics_document->decompress_tmp) { -- argv = extract_argv (document, page->index); -- success = g_spawn_async_with_pipes (NULL, argv, NULL, -- G_SPAWN_SEARCH_PATH | -- G_SPAWN_STDERR_TO_DEV_NULL, -- NULL, NULL, -- &child_pid, -- NULL, &outpipe, NULL, NULL); -- g_strfreev (argv); -- g_return_if_fail (success == TRUE); -- -- loader = gdk_pixbuf_loader_new (); -- g_signal_connect (loader, "area-prepared", -- G_CALLBACK (get_page_size_area_prepared_cb), -- &got_size); -- -- while (outpipe >= 0) { -- bytes = read (outpipe, buf, 1024); -- -- if (bytes > 0) -- gdk_pixbuf_loader_write (loader, buf, bytes, NULL); -- if (bytes <= 0 || got_size) { -- close (outpipe); -- outpipe = -1; -- gdk_pixbuf_loader_close (loader, NULL); -+ -+ const char *page_path; -+ PixbufInfo info; -+ GError *error = NULL; -+ -+ page_path = g_ptr_array_index (comics_document->page_names, page->index); -+ -+ if (!archive_reopen_if_needed (comics_document, page_path, &error)) { -+ g_warning ("Fatal error opening archive: %s", error->message); -+ g_error_free (error); -+ return; -+ } -+ -+ loader = gdk_pixbuf_loader_new (); -+ info.got_info = FALSE; -+ g_signal_connect (loader, "size-prepared", -+ G_CALLBACK (get_page_size_prepared_cb), -+ &info); -+ -+ while (1) { -+ const char *name; -+ GError *error = NULL; -+ -+ if (!ev_archive_read_next_header (comics_document->archive, &error)) { -+ if (error != NULL) { -+ g_warning ("Fatal error handling archive (%s): %s", G_STRFUNC, error->message); -+ g_error_free (error); - } -+ break; - } -- pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); -- if (pixbuf) { -- if (width) -- *width = gdk_pixbuf_get_width (pixbuf); -- if (height) -- *height = gdk_pixbuf_get_height (pixbuf); -- } -- g_spawn_close_pid (child_pid); -- g_object_unref (loader); -- } else { -- filename = g_build_filename (comics_document->dir, -- (char *) comics_document->page_names->pdata[page->index], -- NULL); -- pixbuf = gdk_pixbuf_new_from_file (filename, NULL); -- if (pixbuf) { -- if (width) -- *width = gdk_pixbuf_get_width (pixbuf); -- if (height) -- *height = gdk_pixbuf_get_height (pixbuf); -- g_object_unref (pixbuf); -+ -+ name = ev_archive_get_entry_pathname (comics_document->archive); -+ if (g_strcmp0 (name, page_path) == 0) { -+ char buf[BLOCK_SIZE]; -+ gssize read; -+ gint64 left; -+ -+ left = ev_archive_get_entry_size (comics_document->archive); -+ read = ev_archive_read_data (comics_document->archive, buf, -+ MIN(BLOCK_SIZE, left), &error); -+ while (read > 0 && !info.got_info) { -+ if (!gdk_pixbuf_loader_write (loader, (guchar *) buf, read, &error)) { -+ read = -1; -+ break; -+ } -+ left -= read; -+ read = ev_archive_read_data (comics_document->archive, buf, -+ MIN(BLOCK_SIZE, left), &error); -+ } -+ if (read < 0) { -+ g_warning ("Fatal error reading '%s' in archive: %s", name, error->message); -+ g_error_free (error); -+ } -+ break; - } -- g_free (filename); -+ } -+ -+ gdk_pixbuf_loader_close (loader, NULL); -+ g_object_unref (loader); -+ -+ if (info.got_info) { -+ if (width) -+ *width = info.width; -+ if (height) -+ *height = info.height; - } - } - - static void --get_page_size_area_prepared_cb (GdkPixbufLoader *loader, -- gpointer data) -+render_pixbuf_size_prepared_cb (GdkPixbufLoader *loader, -+ gint width, -+ gint height, -+ EvRenderContext *rc) - { -- gboolean *got_size = data; -- *got_size = TRUE; -+ // int scaled_width, scaled_height; -+ double scale = rc->scale; -+ int w = (width * scale + 0.5); -+ int h = (height * scale + 0.5); -+ -+ // ev_render_context_compute_scaled_size (rc, width, height, &scaled_width, &scaled_height); -+ gdk_pixbuf_loader_set_size (loader, w, h); - } - - static GdkPixbuf * -@@ -731,69 +528,68 @@ comics_document_render_pixbuf (EvDocument *document, - EvRenderContext *rc) - { - GdkPixbufLoader *loader; -- GdkPixbuf *rotated_pixbuf, *tmp_pixbuf; -- char **argv; -- guchar buf[4096]; -- gboolean success; -- gint outpipe = -1; -- GPid child_pid; -- gssize bytes; -- gint width, height; -- gchar *filename; -+ GdkPixbuf *tmp_pixbuf; -+ GdkPixbuf *rotated_pixbuf = NULL; - ComicsDocument *comics_document = COMICS_DOCUMENT (document); -- -- if (!comics_document->decompress_tmp) { -- argv = extract_argv (document, rc->page->index); -- success = g_spawn_async_with_pipes (NULL, argv, NULL, -- G_SPAWN_SEARCH_PATH | -- G_SPAWN_STDERR_TO_DEV_NULL, -- NULL, NULL, -- &child_pid, -- NULL, &outpipe, NULL, NULL); -- g_strfreev (argv); -- g_return_val_if_fail (success == TRUE, NULL); -- -- loader = gdk_pixbuf_loader_new (); -- g_signal_connect (loader, "size-prepared", -- G_CALLBACK (render_pixbuf_size_prepared_cb), -- &rc->scale); -- -- while (outpipe >= 0) { -- bytes = read (outpipe, buf, 4096); -- -- if (bytes > 0) { -- gdk_pixbuf_loader_write (loader, buf, bytes, -- NULL); -- } else if (bytes <= 0) { -- close (outpipe); -- gdk_pixbuf_loader_close (loader, NULL); -- outpipe = -1; -+ const char *page_path; -+ GError *error = NULL; -+ -+ page_path = g_ptr_array_index (comics_document->page_names, rc->page->index); -+ -+ if (!archive_reopen_if_needed (comics_document, page_path, &error)) { -+ g_warning ("Fatal error opening archive: %s", error->message); -+ g_error_free (error); -+ return NULL; -+ } -+ -+ loader = gdk_pixbuf_loader_new (); -+ g_signal_connect (loader, "size-prepared", -+ G_CALLBACK (render_pixbuf_size_prepared_cb), -+ rc); -+ -+ while (1) { -+ const char *name; -+ -+ if (!ev_archive_read_next_header (comics_document->archive, &error)) { -+ if (error != NULL) { -+ g_warning ("Fatal error handling archive (%s): %s", G_STRFUNC, error->message); -+ g_error_free (error); - } -+ break; - } -- tmp_pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); -- rotated_pixbuf = -- gdk_pixbuf_rotate_simple (tmp_pixbuf, -- 360 - rc->rotation); -- g_spawn_close_pid (child_pid); -- g_object_unref (loader); -- } else { -- filename = -- g_build_filename (comics_document->dir, -- (char *) comics_document->page_names->pdata[rc->page->index], -- NULL); -- -- gdk_pixbuf_get_file_info (filename, &width, &height); -- -- tmp_pixbuf = -- gdk_pixbuf_new_from_file_at_size ( -- filename, width * (rc->scale) + 0.5, -- height * (rc->scale) + 0.5, NULL); -- rotated_pixbuf = -- gdk_pixbuf_rotate_simple (tmp_pixbuf, -- 360 - rc->rotation); -- g_free (filename); -- g_object_unref (tmp_pixbuf); -+ -+ name = ev_archive_get_entry_pathname (comics_document->archive); -+ if (g_strcmp0 (name, page_path) == 0) { -+ size_t size = ev_archive_get_entry_size (comics_document->archive); -+ char *buf; -+ ssize_t read; -+ -+ buf = g_malloc (size); -+ read = ev_archive_read_data (comics_document->archive, buf, size, &error); -+ if (read <= 0) { -+ if (read < 0) { -+ g_warning ("Fatal error reading '%s' in archive: %s", name, error->message); -+ g_error_free (error); -+ } else { -+ g_warning ("Read an empty file from the archive"); -+ } -+ } else { -+ gdk_pixbuf_loader_write (loader, (guchar *) buf, size, NULL); -+ } -+ g_free (buf); -+ gdk_pixbuf_loader_close (loader, NULL); -+ break; -+ } -+ } -+ tmp_pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); -+ if (tmp_pixbuf) { -+ if ((rc->rotation % 360) == 0) -+ rotated_pixbuf = g_object_ref (tmp_pixbuf); -+ else -+ rotated_pixbuf = gdk_pixbuf_rotate_simple (tmp_pixbuf, -+ 360 - rc->rotation); - } -+ g_object_unref (loader); - return rotated_pixbuf; - } - -@@ -805,79 +601,26 @@ comics_document_render (EvDocument *document, - cairo_surface_t *surface; - - pixbuf = comics_document_render_pixbuf (document, rc); -+ if (!pixbuf) -+ return NULL; - surface = ev_document_misc_surface_from_pixbuf (pixbuf); -- g_object_unref (pixbuf); -- -+ g_clear_object (&pixbuf); - return surface; - } - --static void --render_pixbuf_size_prepared_cb (GdkPixbufLoader *loader, -- gint width, -- gint height, -- gpointer data) --{ -- double *scale = data; -- int w = (width * (*scale) + 0.5); -- int h = (height * (*scale) + 0.5); -- -- gdk_pixbuf_loader_set_size (loader, w, h); --} -- --/** -- * comics_remove_dir: Removes a directory recursively. -- * Returns: -- * 0 if it was successfully deleted, -- * -1 if an error occurred -- */ --static int --comics_remove_dir (gchar *path_name) --{ -- GDir *content_dir; -- const gchar *filename; -- gchar *filename_with_path; -- -- if (g_file_test (path_name, G_FILE_TEST_IS_DIR)) { -- content_dir = g_dir_open (path_name, 0, NULL); -- filename = g_dir_read_name (content_dir); -- while (filename) { -- filename_with_path = -- g_build_filename (path_name, -- filename, NULL); -- comics_remove_dir (filename_with_path); -- g_free (filename_with_path); -- filename = g_dir_read_name (content_dir); -- } -- g_dir_close (content_dir); -- } -- /* Note from g_remove() documentation: on Windows, it is in general not -- * possible to remove a file that is open to some process, or mapped -- * into memory.*/ -- return (g_remove (path_name)); --} -- - static void - comics_document_finalize (GObject *object) - { - ComicsDocument *comics_document = COMICS_DOCUMENT (object); -- -- if (comics_document->decompress_tmp) { -- if (comics_remove_dir (comics_document->dir) == -1) -- g_warning (_("There was an error deleting “%s”."), -- comics_document->dir); -- g_free (comics_document->dir); -- } -- -+ - if (comics_document->page_names) { - g_ptr_array_foreach (comics_document->page_names, (GFunc) g_free, NULL); - g_ptr_array_free (comics_document->page_names, TRUE); - } -- -- g_free (comics_document->archive); -- g_free (comics_document->selected_command); -- g_free (comics_document->alternative_command); -- g_free (comics_document->extract_command); -- g_free (comics_document->list_command); -+ g_clear_pointer (&comics_document->page_positions, g_hash_table_destroy); -+ g_clear_object (&comics_document->archive); -+ g_free (comics_document->archive_path); -+ g_free (comics_document->archive_uri); - - G_OBJECT_CLASS (comics_document_parent_class)->finalize (object); - } -@@ -900,33 +643,7 @@ comics_document_class_init (ComicsDocumentClass *klass) - static void - comics_document_init (ComicsDocument *comics_document) - { -- comics_document->archive = NULL; -- comics_document->page_names = NULL; -- comics_document->extract_command = NULL; --} -- --/* Returns a list of file extensions supported by gdk-pixbuf */ --static GSList* --get_supported_image_extensions(void) --{ -- GSList *extensions = NULL; -- GSList *formats = gdk_pixbuf_get_formats (); -- GSList *l; -- -- for (l = formats; l != NULL; l = l->next) { -- int i; -- gchar **ext = gdk_pixbuf_format_get_extensions (l->data); -- -- for (i = 0; ext[i] != NULL; i++) { -- extensions = g_slist_append (extensions, -- g_strdup (ext[i])); -- } -- -- g_strfreev (ext); -- } -- -- g_slist_free (formats); -- return extensions; -+ comics_document->archive = ev_archive_new (); - } - - static GdkPixbuf * -@@ -940,7 +657,7 @@ comics_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, - - if (border) { - GdkPixbuf *tmp_pixbuf = thumbnail; -- -+ - thumbnail = ev_document_misc_get_thumbnail_frame (-1, -1, tmp_pixbuf); - g_object_unref (tmp_pixbuf); - } -@@ -955,7 +672,7 @@ comics_document_thumbnails_get_dimensions (EvDocumentThumbnails *document, - gint *height) - { - gdouble page_width, page_height; -- -+ - comics_document_get_page_size (EV_DOCUMENT (document), rc->page, - &page_width, &page_height); - -@@ -974,48 +691,3 @@ comics_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *i - iface->get_thumbnail = comics_document_thumbnails_get_thumbnail; - iface->get_dimensions = comics_document_thumbnails_get_dimensions; - } -- --static char** --extract_argv (EvDocument *document, gint page) --{ -- ComicsDocument *comics_document = COMICS_DOCUMENT (document); -- char **argv; -- char *command_line, *quoted_archive, *quoted_filename; -- GError *err = NULL; -- -- if (g_strrstr (comics_document->page_names->pdata[page], "--checkpoint-action=")) -- { -- g_warning ("File unsupported\n"); -- gtk_main_quit (); -- } -- -- if (page >= comics_document->page_names->len) -- return NULL; -- -- if (comics_document->regex_arg) { -- quoted_archive = g_shell_quote (comics_document->archive); -- quoted_filename = -- comics_regex_quote (comics_document->page_names->pdata[page]); -- } else { -- quoted_archive = g_shell_quote (comics_document->archive); -- quoted_filename = g_shell_quote (comics_document->page_names->pdata[page]); -- } -- -- command_line = g_strdup_printf ("%s %s %s", -- comics_document->extract_command, -- quoted_archive, -- quoted_filename); -- g_free (quoted_archive); -- g_free (quoted_filename); -- -- g_shell_parse_argv (command_line, NULL, &argv, &err); -- g_free (command_line); -- -- if (err) { -- g_warning (_("Error %s"), err->message); -- g_error_free (err); -- return NULL; -- } -- -- return argv; --} -diff --git a/backend/comics/comics-document.h b/backend/comics/comics-document.h -index 6cc55f0..4417a69 100644 ---- a/backend/comics/comics-document.h -+++ b/backend/comics/comics-document.h -@@ -16,9 +16,9 @@ - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - --#ifndef __COMICS_DOCUMENT_H__ --#define __COMICS_DOCUMENT_H__ -+#pragma once - -+#include "ev-macros.h" - #include "ev-document.h" - - G_BEGIN_DECLS -@@ -30,9 +30,8 @@ G_BEGIN_DECLS - typedef struct _ComicsDocument ComicsDocument; - - GType comics_document_get_type (void) G_GNUC_CONST; -+GType register_atril_backend (GTypeModule *module); -+ - --G_MODULE_EXPORT GType register_atril_backend (GTypeModule *module); -- - G_END_DECLS - --#endif /* __COMICS_DOCUMENT_H__ */ -diff --git a/backend/comics/ev-archive.c b/backend/comics/ev-archive.c -new file mode 100644 -index 0000000..568e162 ---- /dev/null -+++ b/backend/comics/ev-archive.c -@@ -0,0 +1,323 @@ -+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ -+/* -+ * Copyright (C) 2017, Bastien Nocera -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include "config.h" -+#include "ev-archive.h" -+ -+#include -+#include -+#include -+ -+#define BUFFER_SIZE (64 * 1024) -+ -+struct _EvArchive { -+ GObject parent_instance; -+ EvArchiveType type; -+ -+ /* libarchive */ -+ struct archive *libar; -+ struct archive_entry *libar_entry; -+}; -+ -+G_DEFINE_TYPE(EvArchive, ev_archive, G_TYPE_OBJECT); -+ -+static void -+ev_archive_finalize (GObject *object) -+{ -+ EvArchive *archive = EV_ARCHIVE (object); -+ -+ switch (archive->type) { -+ case EV_ARCHIVE_TYPE_RAR: -+ case EV_ARCHIVE_TYPE_ZIP: -+ case EV_ARCHIVE_TYPE_7Z: -+ case EV_ARCHIVE_TYPE_TAR: -+ g_clear_pointer (&archive->libar, archive_free); -+ break; -+ default: -+ break; -+ } -+ -+ G_OBJECT_CLASS (ev_archive_parent_class)->finalize (object); -+} -+ -+static void -+ev_archive_class_init (EvArchiveClass *klass) -+{ -+ GObjectClass *object_class = (GObjectClass *) klass; -+ -+ object_class->finalize = ev_archive_finalize; -+} -+ -+EvArchive * -+ev_archive_new (void) -+{ -+ return g_object_new (EV_TYPE_ARCHIVE, NULL); -+} -+ -+static void -+libarchive_set_archive_type (EvArchive *archive, -+ EvArchiveType archive_type) -+{ -+ archive->type = archive_type; -+ archive->libar = archive_read_new (); -+ -+ if (archive_type == EV_ARCHIVE_TYPE_ZIP) -+ archive_read_support_format_zip (archive->libar); -+ else if (archive_type == EV_ARCHIVE_TYPE_7Z) -+ archive_read_support_format_7zip (archive->libar); -+ else if (archive_type == EV_ARCHIVE_TYPE_TAR) -+ archive_read_support_format_tar (archive->libar); -+ else if (archive_type == EV_ARCHIVE_TYPE_RAR) { -+ archive_read_support_format_rar (archive->libar); -+ archive_read_support_format_rar5 (archive->libar); -+ } else -+ g_assert_not_reached (); -+} -+ -+EvArchiveType -+ev_archive_get_archive_type (EvArchive *archive) -+{ -+ g_return_val_if_fail (EV_IS_ARCHIVE (archive), EV_ARCHIVE_TYPE_NONE); -+ -+ return archive->type; -+} -+ -+gboolean -+ev_archive_set_archive_type (EvArchive *archive, -+ EvArchiveType archive_type) -+{ -+ g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE); -+ g_return_val_if_fail (archive->type == EV_ARCHIVE_TYPE_NONE, FALSE); -+ -+ switch (archive_type) { -+ case EV_ARCHIVE_TYPE_RAR: -+ case EV_ARCHIVE_TYPE_ZIP: -+ case EV_ARCHIVE_TYPE_7Z: -+ case EV_ARCHIVE_TYPE_TAR: -+ libarchive_set_archive_type (archive, archive_type); -+ break; -+ default: -+ g_assert_not_reached (); -+ } -+ -+ return TRUE; -+} -+ -+gboolean -+ev_archive_open_filename (EvArchive *archive, -+ const char *path, -+ GError **error) -+{ -+ int r; -+ -+ g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE); -+ g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, FALSE); -+ g_return_val_if_fail (path != NULL, FALSE); -+ -+ switch (archive->type) { -+ case EV_ARCHIVE_TYPE_NONE: -+ g_assert_not_reached (); -+ case EV_ARCHIVE_TYPE_RAR: -+ case EV_ARCHIVE_TYPE_ZIP: -+ case EV_ARCHIVE_TYPE_7Z: -+ case EV_ARCHIVE_TYPE_TAR: -+ r = archive_read_open_filename (archive->libar, path, BUFFER_SIZE); -+ if (r != ARCHIVE_OK) { -+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, -+ "Error opening archive: %s", archive_error_string (archive->libar)); -+ return FALSE; -+ } -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+static gboolean -+libarchive_read_next_header (EvArchive *archive, -+ GError **error) -+{ -+ while (1) { -+ int r; -+ -+ r = archive_read_next_header (archive->libar, &archive->libar_entry); -+ if (r != ARCHIVE_OK) { -+ if (r != ARCHIVE_EOF) -+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, -+ "Error reading archive: %s", archive_error_string (archive->libar)); -+ return FALSE; -+ } -+ -+ if (archive_entry_filetype (archive->libar_entry) != AE_IFREG) { -+ g_debug ("Skipping '%s' as it's not a regular file", -+ archive_entry_pathname (archive->libar_entry)); -+ continue; -+ } -+ -+ g_debug ("At header for file '%s'", archive_entry_pathname (archive->libar_entry)); -+ -+ break; -+ } -+ -+ return TRUE; -+} -+ -+gboolean -+ev_archive_read_next_header (EvArchive *archive, -+ GError **error) -+{ -+ g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE); -+ g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, FALSE); -+ -+ switch (archive->type) { -+ case EV_ARCHIVE_TYPE_NONE: -+ g_assert_not_reached (); -+ case EV_ARCHIVE_TYPE_RAR: -+ case EV_ARCHIVE_TYPE_ZIP: -+ case EV_ARCHIVE_TYPE_7Z: -+ case EV_ARCHIVE_TYPE_TAR: -+ return libarchive_read_next_header (archive, error); -+ } -+ -+ return FALSE; -+} -+ -+gboolean -+ev_archive_at_entry (EvArchive *archive) -+{ -+ g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE); -+ g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, FALSE); -+ -+ return (archive->libar_entry != NULL); -+} -+ -+const char * -+ev_archive_get_entry_pathname (EvArchive *archive) -+{ -+ g_return_val_if_fail (EV_IS_ARCHIVE (archive), NULL); -+ g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, NULL); -+ -+ switch (archive->type) { -+ case EV_ARCHIVE_TYPE_NONE: -+ g_assert_not_reached (); -+ case EV_ARCHIVE_TYPE_RAR: -+ case EV_ARCHIVE_TYPE_ZIP: -+ case EV_ARCHIVE_TYPE_7Z: -+ case EV_ARCHIVE_TYPE_TAR: -+ g_return_val_if_fail (archive->libar_entry != NULL, NULL); -+ return archive_entry_pathname (archive->libar_entry); -+ } -+ -+ return NULL; -+} -+ -+gint64 -+ev_archive_get_entry_size (EvArchive *archive) -+{ -+ g_return_val_if_fail (EV_IS_ARCHIVE (archive), -1); -+ g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, -1); -+ -+ switch (archive->type) { -+ case EV_ARCHIVE_TYPE_NONE: -+ g_assert_not_reached (); -+ case EV_ARCHIVE_TYPE_RAR: -+ case EV_ARCHIVE_TYPE_ZIP: -+ case EV_ARCHIVE_TYPE_7Z: -+ case EV_ARCHIVE_TYPE_TAR: -+ g_return_val_if_fail (archive->libar_entry != NULL, -1); -+ return archive_entry_size (archive->libar_entry); -+ } -+ -+ return -1; -+} -+ -+gboolean -+ev_archive_get_entry_is_encrypted (EvArchive *archive) -+{ -+ g_return_val_if_fail (EV_IS_ARCHIVE (archive), FALSE); -+ g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, FALSE); -+ -+ switch (archive->type) { -+ case EV_ARCHIVE_TYPE_NONE: -+ g_assert_not_reached (); -+ case EV_ARCHIVE_TYPE_RAR: -+ case EV_ARCHIVE_TYPE_ZIP: -+ case EV_ARCHIVE_TYPE_7Z: -+ case EV_ARCHIVE_TYPE_TAR: -+ g_return_val_if_fail (archive->libar_entry != NULL, -1); -+ return archive_entry_is_encrypted (archive->libar_entry); -+ } -+ -+ return FALSE; -+} -+ -+gssize -+ev_archive_read_data (EvArchive *archive, -+ void *buf, -+ gsize count, -+ GError **error) -+{ -+ gssize r = -1; -+ -+ g_return_val_if_fail (EV_IS_ARCHIVE (archive), -1); -+ g_return_val_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE, -1); -+ -+ switch (archive->type) { -+ case EV_ARCHIVE_TYPE_NONE: -+ g_assert_not_reached (); -+ case EV_ARCHIVE_TYPE_RAR: -+ case EV_ARCHIVE_TYPE_ZIP: -+ case EV_ARCHIVE_TYPE_7Z: -+ case EV_ARCHIVE_TYPE_TAR: -+ g_return_val_if_fail (archive->libar_entry != NULL, -1); -+ r = archive_read_data (archive->libar, buf, count); -+ if (r < 0) { -+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, -+ "Failed to decompress data: %s", archive_error_string (archive->libar)); -+ } -+ break; -+ } -+ -+ return r; -+} -+ -+void -+ev_archive_reset (EvArchive *archive) -+{ -+ g_return_if_fail (EV_IS_ARCHIVE (archive)); -+ g_return_if_fail (archive->type != EV_ARCHIVE_TYPE_NONE); -+ -+ switch (archive->type) { -+ case EV_ARCHIVE_TYPE_RAR: -+ case EV_ARCHIVE_TYPE_ZIP: -+ case EV_ARCHIVE_TYPE_7Z: -+ case EV_ARCHIVE_TYPE_TAR: -+ g_clear_pointer (&archive->libar, archive_free); -+ libarchive_set_archive_type (archive, archive->type); -+ archive->libar_entry = NULL; -+ break; -+ default: -+ g_assert_not_reached (); -+ } -+} -+ -+static void -+ev_archive_init (EvArchive *archive) -+{ -+} -diff --git a/backend/comics/ev-archive.h b/backend/comics/ev-archive.h -new file mode 100644 -index 0000000..b4e1399 ---- /dev/null -+++ b/backend/comics/ev-archive.h -@@ -0,0 +1,56 @@ -+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ -+/* -+ * Copyright (C) 2017, Bastien Nocera -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#pragma once -+ -+#include -+ -+G_BEGIN_DECLS -+ -+#define EV_TYPE_ARCHIVE ev_archive_get_type () -+G_DECLARE_FINAL_TYPE (EvArchive, ev_archive, EV, ARCHIVE, GObject) -+ -+typedef enum { -+ EV_ARCHIVE_TYPE_NONE = 0, -+ EV_ARCHIVE_TYPE_RAR, -+ EV_ARCHIVE_TYPE_ZIP, -+ EV_ARCHIVE_TYPE_7Z, -+ EV_ARCHIVE_TYPE_TAR -+} EvArchiveType; -+ -+EvArchive *ev_archive_new (void); -+gboolean ev_archive_set_archive_type (EvArchive *archive, -+ EvArchiveType archive_type); -+EvArchiveType ev_archive_get_archive_type (EvArchive *archive); -+gboolean ev_archive_open_filename (EvArchive *archive, -+ const char *path, -+ GError **error); -+gboolean ev_archive_read_next_header (EvArchive *archive, -+ GError **error); -+gboolean ev_archive_at_entry (EvArchive *archive); -+const char *ev_archive_get_entry_pathname (EvArchive *archive); -+gint64 ev_archive_get_entry_size (EvArchive *archive); -+gboolean ev_archive_get_entry_is_encrypted (EvArchive *archive); -+gssize ev_archive_read_data (EvArchive *archive, -+ void *buf, -+ gsize count, -+ GError **error); -+void ev_archive_reset (EvArchive *archive); -+ -+G_END_DECLS -diff --git a/configure.ac b/configure.ac -index 90d2f09..5fced50 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -560,8 +560,11 @@ AC_ARG_ENABLE(comics, - [enable_comics=$enableval], - [enable_comics=yes]) - -+COMICS_DEPS="libarchive" - if test "x$enable_comics" = "xyes"; then - AC_DEFINE([ENABLE_COMICS], [1], [Enable support for comics.]) -+ PKG_CHECK_MODULES([COMICS], [$COMICS_DEPS]) -+ AC_SUBST(COMICS_LIBS) - fi - AM_CONDITIONAL(ENABLE_COMICS, test x$enable_comics = xyes) - -diff --git a/libdocument/ev-document.h b/libdocument/ev-document.h -index 6c492da..d57d002 100644 ---- a/libdocument/ev-document.h -+++ b/libdocument/ev-document.h -@@ -56,6 +56,7 @@ typedef struct _EvDocumentPrivate EvDocumentPrivate; - typedef enum - { - EV_DOCUMENT_ERROR_INVALID, -+ EV_DOCUMENT_ERROR_UNSUPPORTED_CONTENT, - EV_DOCUMENT_ERROR_ENCRYPTED - } EvDocumentError; - --- -2.43.0 - diff --git a/CVE-2023-52076.patch b/CVE-2023-52076.patch deleted file mode 100644 index 6595bf9f6c401cf6df3115db5deaa75ab4f87531..0000000000000000000000000000000000000000 --- a/CVE-2023-52076.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 0fd1bfdbb81dddeb2329137315ce17684a6602c2 Mon Sep 17 00:00:00 2001 -From: peijiankang -Date: Thu, 29 Feb 2024 10:34:25 +0800 -Subject: [PATCH] CVE-2023-52076 - ---- - backend/epub/epub-document.c | 24 ++++++++++++++++++++---- - 1 file changed, 20 insertions(+), 4 deletions(-) - -diff --git a/backend/epub/epub-document.c b/backend/epub/epub-document.c -index c0fa275..b0d42a3 100644 ---- a/backend/epub/epub-document.c -+++ b/backend/epub/epub-document.c -@@ -653,7 +653,7 @@ check_mime_type(const gchar* uri,GError** error) - } - - 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; -@@ -680,6 +680,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') - { -@@ -707,7 +721,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 ) -@@ -720,10 +733,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) ; - - out: -+ g_object_unref(outfile) ; - unzCloseCurrentFile (epub_document->epubDocument) ; - g_string_free(gfilepath,TRUE); - g_free(currentfilename); -@@ -735,6 +748,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); - -@@ -796,9 +810,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); -@@ -819,6 +834,7 @@ extract_epub_from_container (const gchar* uri, - } - - out: -+ g_clear_object (&tmp_gfile); - unzClose(epub_document->epubDocument); - return result; - } --- -2.41.0 - diff --git a/atril-1.22.3.tar.xz b/atril-1.22.3.tar.xz deleted file mode 100644 index 940ce2b4c82d7787c9654f34082e338fc46cd59a..0000000000000000000000000000000000000000 Binary files a/atril-1.22.3.tar.xz and /dev/null differ diff --git a/atril-1.28.1.tar.xz b/atril-1.28.1.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..68e75bbc19606e69e5e60cd5d9aa36778a00b291 Binary files /dev/null and b/atril-1.28.1.tar.xz differ diff --git a/atril.spec b/atril.spec index 8eea432e4e64430ded3fd8a5eb648a374e13fe55..d2365509b204dc9036a9628bdde8d07b29e7edbf 100644 --- a/atril.spec +++ b/atril.spec @@ -1,63 +1,40 @@ -# Conditional for release and snapshot builds. Uncomment for release-builds. -%global rel_build 1 - -# This is needed, because src-url contains branched part of versioning-scheme. -%global branch 1.22 - -# Settings used for build from snapshots. -%{!?rel_build:%global commit 5bba3723566489763aafaad3669c77f60a23d2e0} -%{!?rel_build:%global commit_date 20140122} -%{!?rel_build:%global shortcommit %(c=%{commit};echo ${c:0:7})} -%{!?rel_build:%global git_ver git%{commit_date}-%{shortcommit}} -%{!?rel_build:%global git_rel .git%{commit_date}.%{shortcommit}} -%{!?rel_build:%global git_tar %{name}-%{version}-%{git_ver}.tar.xz} - Name: atril -Version: %{branch}.3 -Release: 6 +Version: 1.28.1 +Release: 1 Summary: Document viewer License: GPLv2+ and LGPLv2+ and MIT URL: http://mate-desktop.org - -# for downloading the tarball use 'spectool -g -R caja.spec' -# Source for release-builds. -%{?rel_build:Source0: http://pub.mate-desktop.org/releases/%{branch}/%{name}-%{version}.tar.xz} -# Source for snapshot-builds. -%{!?rel_build:Source0: http://git.mate-desktop.org/%{name}/snapshot/%{name}-%{commit}.tar.xz#/%{git_tar}} -Patch01: CVE-2023-52076.patch -#fix from https://gitee.com/link?target=https%3A%2F%2Fgithub.com%2Fmate-desktop%2Fatril%2Fcommit%2Fce41df6467521ff9fd4f16514ae7d6ebb62eb1ed -Patch02: CVE-2023-51698.patch -Patch03: fix-build-error-check-aclocal-version.patch -Patch04: backport-use-webkit2gtk-4.1.patch - -BuildRequires: gcc-c++ -BuildRequires: gtk3-devel -BuildRequires: poppler-glib-devel -BuildRequires: libXt-devel -BuildRequires: libsecret-devel -BuildRequires: libglade2-devel -BuildRequires: libtiff-devel -BuildRequires: libjpeg-turbo-devel -BuildRequires: libspectre-devel -BuildRequires: desktop-file-utils -BuildRequires: gobject-introspection-devel -BuildRequires: mate-common -BuildRequires: cairo-gobject-devel -BuildRequires: yelp-tools +Source0: http://pub.mate-desktop.org/releases/1.28/%{name}-%{version}.tar.xz + +BuildRequires: gcc-c++ +BuildRequires: gtk3-devel +BuildRequires: poppler-glib-devel +BuildRequires: libarchive-devel +BuildRequires: libXt-devel +BuildRequires: libsecret-devel +BuildRequires: libtiff-devel +BuildRequires: libjpeg-turbo-devel +BuildRequires: libspectre-devel +BuildRequires: desktop-file-utils +BuildRequires: gobject-introspection-devel +BuildRequires: make +BuildRequires: mate-common +BuildRequires: mate-desktop-devel +BuildRequires: cairo-gobject-devel +BuildRequires: yelp-tools # for the xps back-end -BuildRequires: libgxps-devel +BuildRequires: libgxps-devel # for the caja properties page -#BuildRequires: caja-devel +BuildRequires: caja-devel # for the dvi back-end -BuildRequires: texlive-lib-devel +BuildRequires: texlive-lib-devel # for the djvu back-end -BuildRequires: djvulibre-devel +BuildRequires: djvulibre-devel # for epub back-end -BuildRequires: pkgconfig(webkit2gtk-4.1) +BuildRequires: webkit2gtk4.1-devel Requires: %{name}-libs%{?_isa} = %{version}-%{release} -# fix (#974791) Requires: mate-desktop-libs Requires: mathjax @@ -85,25 +62,35 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} This package contains libraries and header files needed for mate-document-viewer back-ends development. + +%package caja +Summary: Mate-document-viewer extension for caja +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: caja + +%description caja +This package contains the mate-document-viewer extension for the +caja file manager. +It adds an additional tab called "Document" to the file properties dialog. + +%package thumbnailer +Summary: Atril thumbnailer extension for caja +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: caja + +%description thumbnailer +This package contains the atril extension for the +caja file manager. + + %prep -%if 0%{?rel_build} %autosetup -p1 -%else -%autosetup -n %{name}-%{commit} -p1 -%endif - -%if 0%{?rel_build} -NOCONFIGURE=1 ./autogen.sh -%else # 0%{?rel_build} -# needed for git snapshots -NOCONFIGURE=1 ./autogen.sh -%endif # 0%{?rel_build} %build +CFLAGS="%{optflags} -I/usr/include/synctex" %configure \ --disable-static \ --disable-schemas-compile \ - --disable-caja \ --enable-introspection \ --enable-comics \ --enable-dvi=yes \ @@ -111,27 +98,29 @@ NOCONFIGURE=1 ./autogen.sh --enable-t1lib=no \ --enable-pixbuf \ --enable-xps \ - --enable-epub + --enable-epub \ + --enable-synctex # remove unused-direct-shlib-dependency sed -i -e 's! -shared ! -Wl,--as-needed\0!g' libtool -%make_build +make %{?_smp_mflags} V=1 %install %{make_install} -%delete_la %find_lang %{name} --with-gnome --all-name +find $RPM_BUILD_ROOT -name '*.la' -exec rm -fv {} ';' + %check desktop-file-validate ${RPM_BUILD_ROOT}%{_datadir}/applications/atril.desktop %files -f %{name}.lang -%doc README COPYING NEWS AUTHORS +%doc README.md COPYING NEWS AUTHORS %{_bindir}/* %dir %{_datadir}/atril %{_datadir}/atril/* @@ -151,7 +140,12 @@ desktop-file-validate ${RPM_BUILD_ROOT}%{_datadir}/applications/atril.desktop %{_libdir}/girepository-1.0/AtrilDocument-1.5.0.typelib %{_libdir}/girepository-1.0/AtrilView-1.5.0.typelib -%exclude %{_datadir}/thumbnailers/atril.thumbnailer +%files caja +%{_libdir}/caja/extensions-2.0/libatril-properties-page.so +%{_datadir}/caja/extensions/libatril-properties-page.caja-extension + +%files thumbnailer +%{_datadir}/thumbnailers/atril.thumbnailer %files devel %dir %{_includedir}/atril/ @@ -168,21 +162,5 @@ desktop-file-validate ${RPM_BUILD_ROOT}%{_datadir}/applications/atril.desktop %changelog -* Thu Dec 26 2024 Funda Wang - 1.22.3-6 -- use webkitgtk-4.1 - -* Thu Aug 15 2024 zhangxianting - 1.22.3-5 -- fix build error, check aclocal version - -* Wed Apr 24 2024 peijiankang - 1.22.3-4 -- add CVE-2023-51698.patch - -* Thu Feb 29 2024 peijiankang - 1.22.3-3 -- add CVE-2023-52076.patch - -* Tue Jun 1 2021 douyan - 1.22.3-2 -- remove package atril-thumbnailer - -* Tue Aug 25 2020 douyan - 1.22.3-1 -- disable caja support. Init package for openEuler - +* Mon Mar 17 2025 yuanxing - 1.28.1-1 +- Initial build diff --git a/backport-use-webkit2gtk-4.1.patch b/backport-use-webkit2gtk-4.1.patch deleted file mode 100644 index 10d8b06b7b0317dae7dad3fbf3f6ac7e0c8a2b18..0000000000000000000000000000000000000000 --- a/backport-use-webkit2gtk-4.1.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 92f7d054d2a534bb08f92821e910625ecc0a3760 Mon Sep 17 00:00:00 2001 -From: raveit65 -Date: Thu, 4 May 2023 13:13:22 +0200 -Subject: use webkit2gtk-4.1 - -- fixes https://github.com/mate-desktop/atril/issues/582 ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index dbdf2b47..9783c8aa 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -622,7 +622,7 @@ AC_ARG_ENABLE(epub, - - have_webkit="no" - if test "x$enable_epub" = "xyes"; then -- PKG_CHECK_MODULES(EPUB, webkit2gtk-4.0 >= $WEBKIT_REQUIRED \ -+ PKG_CHECK_MODULES(EPUB, webkit2gtk-4.1 >= $WEBKIT_REQUIRED \ - libxml-2.0 >= $LIBXML_REQUIRED zlib,have_webkit=yes,have_webkit=no) - if test "x$have_webkit" = "xno"; then - AC_MSG_NOTICE([Webkit2 4.0 not found, trying 3.0]) --- -cgit v1.2.1 diff --git a/fix-build-error-check-aclocal-version.patch b/fix-build-error-check-aclocal-version.patch deleted file mode 100644 index 3b34497ed79a3c5bb7e5d71412bbf9565435114a..0000000000000000000000000000000000000000 --- a/fix-build-error-check-aclocal-version.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 3554f6eacb571c875f46b44f87715ac8a5ae6215 Mon Sep 17 00:00:00 2001 -From: zhangxianting -Date: Thu, 15 Aug 2024 15:38:07 +0800 -Subject: [PATCH] fix build error check aclocal version - ---- - configure | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/configure b/configure -index e3ad2d3..c56b580 100755 ---- a/configure -+++ b/configure -@@ -3045,6 +3045,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - am__api_version='1.16' -+# Check aclocal version -+if test "$ACLOCAL" != "no"; then -+ am__api_version=$(aclocal --version | head -n1 | awk '{print $NF}') -+fi - - ac_aux_dir= - for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do --- -2.43.0 -