mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-28 07:56:47 +01:00
Reduce amount of leaked memory by libmagic
libmagic always leaks 48 bytes. Now we leak those bytes only once instead of every content type detection. Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
This commit is contained in:
parent
d1c38a703c
commit
e550ab66ee
8 changed files with 123 additions and 41 deletions
|
@ -17,14 +17,23 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
/** Read a most GT_MAX_READ bytes before falling back to file. */
|
struct zathura_content_type_context_s
|
||||||
static const size_t GT_MAX_READ = 1 << 16;
|
{
|
||||||
|
#ifdef WITH_MAGIC
|
||||||
|
magic_t magic;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
zathura_content_type_context_t*
|
||||||
|
zathura_content_type_new(void)
|
||||||
|
{
|
||||||
|
zathura_content_type_context_t* context =
|
||||||
|
g_try_malloc0(sizeof(zathura_content_type_context_t));
|
||||||
|
if (context == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_MAGIC
|
#ifdef WITH_MAGIC
|
||||||
static const char*
|
|
||||||
guess_type_magic(const char* path) {
|
|
||||||
const char* mime_type = NULL;
|
|
||||||
|
|
||||||
/* creat magic cookie */
|
/* creat magic cookie */
|
||||||
const int flags =
|
const int flags =
|
||||||
MAGIC_MIME_TYPE |
|
MAGIC_MIME_TYPE |
|
||||||
|
@ -36,31 +45,63 @@ guess_type_magic(const char* path) {
|
||||||
magic_t magic = magic_open(flags);
|
magic_t magic = magic_open(flags);
|
||||||
if (magic == NULL) {
|
if (magic == NULL) {
|
||||||
girara_debug("failed creating the magic cookie");
|
girara_debug("failed creating the magic cookie");
|
||||||
goto cleanup;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ... and load mime database */
|
/* ... and load mime database */
|
||||||
if (magic_load(magic, NULL) < 0) {
|
if (magic_load(magic, NULL) < 0) {
|
||||||
girara_debug("failed loading the magic database: %s", magic_error(magic));
|
girara_debug("failed loading the magic database: %s", magic_error(magic));
|
||||||
goto cleanup;
|
magic_close(magic);
|
||||||
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context->magic = magic;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zathura_content_type_free(zathura_content_type_context_t* context)
|
||||||
|
{
|
||||||
|
if (context == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_MAGIC
|
||||||
|
if (context->magic != NULL) {
|
||||||
|
magic_close(context->magic);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_free(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Read a most GT_MAX_READ bytes before falling back to file. */
|
||||||
|
static const size_t GT_MAX_READ = 1 << 16;
|
||||||
|
|
||||||
|
#ifdef WITH_MAGIC
|
||||||
|
static const char*
|
||||||
|
guess_type_magic(zathura_content_type_context_t* context, const char* path)
|
||||||
|
{
|
||||||
|
if (context == NULL || context->magic == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* mime_type = NULL;
|
||||||
|
|
||||||
/* get the mime type */
|
/* get the mime type */
|
||||||
mime_type = magic_file(magic, path);
|
mime_type = magic_file(context->magic, path);
|
||||||
if (mime_type == NULL) {
|
if (mime_type == NULL) {
|
||||||
girara_debug("failed guessing filetype: %s", magic_error(magic));
|
girara_debug("failed guessing filetype: %s", magic_error(context->magic));
|
||||||
goto cleanup;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* dup so we own the memory */
|
/* dup so we own the memory */
|
||||||
mime_type = g_strdup(mime_type);
|
mime_type = g_strdup(mime_type);
|
||||||
|
|
||||||
girara_debug("magic detected filetype: %s", mime_type);
|
girara_debug("magic detected filetype: %s", mime_type);
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (magic != NULL) {
|
|
||||||
magic_close(magic);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mime_type;
|
return mime_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +112,9 @@ guess_type_file(const char* UNUSED(path))
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static const char*
|
static const char*
|
||||||
guess_type_magic(const char* UNUSED(path)) {
|
guess_type_magic(zathura_content_type_context_t* UNUSED(context),
|
||||||
|
const char* UNUSED(path))
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,10 +204,11 @@ guess_type_glib(const char* path)
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
guess_content_type(const char* path)
|
zathura_content_type_guess(zathura_content_type_context_t* context,
|
||||||
|
const char* path)
|
||||||
{
|
{
|
||||||
/* try libmagic first */
|
/* try libmagic first */
|
||||||
const char* content_type = guess_type_magic(path);
|
const char* content_type = guess_type_magic(context, path);
|
||||||
if (content_type != NULL) {
|
if (content_type != NULL) {
|
||||||
return content_type;
|
return content_type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,22 @@
|
||||||
#ifndef ZATHURA_CONTENT_TYPE_H
|
#ifndef ZATHURA_CONTENT_TYPE_H
|
||||||
#define ZATHURA_CONTENT_TYPE_H
|
#define ZATHURA_CONTENT_TYPE_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new context for MIME type detection.
|
||||||
|
*
|
||||||
|
* @return new context
|
||||||
|
*/
|
||||||
|
zathura_content_type_context_t* zathura_content_type_new(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free MIME type detection context.
|
||||||
|
*
|
||||||
|
* @param context The context.
|
||||||
|
*/
|
||||||
|
void zathura_content_type_free(zathura_content_type_context_t* context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Guess" the content type of a file. Various methods are tried depending on
|
* "Guess" the content type of a file. Various methods are tried depending on
|
||||||
* the available libraries.
|
* the available libraries.
|
||||||
|
@ -10,6 +26,7 @@
|
||||||
* @param path file name
|
* @param path file name
|
||||||
* @return content type of path
|
* @return content type of path
|
||||||
*/
|
*/
|
||||||
const char* guess_content_type(const char* path);
|
const char* zathura_content_type_guess(zathura_content_type_context_t* context,
|
||||||
|
const char* path);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,10 +61,10 @@ check_set_error(zathura_error_t* error, zathura_error_t code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
zathura_document_t*
|
zathura_document_t*
|
||||||
zathura_document_open(zathura_plugin_manager_t* plugin_manager, const char*
|
zathura_document_open(zathura_t* zathura, const char* path, const char* uri,
|
||||||
path, const char *uri, const char* password, zathura_error_t* error)
|
const char* password, zathura_error_t* error)
|
||||||
{
|
{
|
||||||
if (path == NULL) {
|
if (zathura == NULL || path == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,14 +87,14 @@ zathura_document_open(zathura_plugin_manager_t* plugin_manager, const char*
|
||||||
goto error_free;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
content_type = guess_content_type(real_path);
|
content_type = zathura_content_type_guess(zathura->content_type_context, real_path);
|
||||||
if (content_type == NULL) {
|
if (content_type == NULL) {
|
||||||
girara_error("Could not determine file type.");
|
girara_error("Could not determine file type.");
|
||||||
check_set_error(error, ZATHURA_ERROR_UNKNOWN);
|
check_set_error(error, ZATHURA_ERROR_UNKNOWN);
|
||||||
goto error_free;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin = zathura_plugin_manager_get_plugin(plugin_manager, content_type);
|
plugin = zathura_plugin_manager_get_plugin(zathura->plugins.manager, content_type);
|
||||||
|
|
||||||
if (plugin == NULL) {
|
if (plugin == NULL) {
|
||||||
girara_error("Unknown file type: '%s'", content_type);
|
girara_error("Unknown file type: '%s'", content_type);
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
/**
|
/**
|
||||||
* Open the document
|
* Open the document
|
||||||
*
|
*
|
||||||
* @param plugin_manager The plugin manager
|
* @param plugin_manager The zathura instance
|
||||||
* @param path Path to the document
|
* @param path Path to the document
|
||||||
* @param password Password of the document or NULL
|
* @param password Password of the document or NULL
|
||||||
* @param error Optional error parameter
|
* @param error Optional error parameter
|
||||||
* @return The document object and NULL if an error occurs
|
* @return The document object and NULL if an error occurs
|
||||||
*/
|
*/
|
||||||
zathura_document_t* zathura_document_open(zathura_plugin_manager_t*
|
zathura_document_t* zathura_document_open(zathura_t* zathura,
|
||||||
plugin_manager, const char* path, const char *uri, const char* password, zathura_error_t*
|
const char* path, const char *uri, const char* password, zathura_error_t*
|
||||||
error);
|
error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -148,7 +148,7 @@ typedef struct zathura_image_s
|
||||||
typedef enum zathura_link_type_e
|
typedef enum zathura_link_type_e
|
||||||
{
|
{
|
||||||
ZATHURA_LINK_INVALID, /**< Invalid type */
|
ZATHURA_LINK_INVALID, /**< Invalid type */
|
||||||
ZATHURA_LINK_NONE, /**< No action */
|
ZATHURA_LINK_NONE, /**< No action */
|
||||||
ZATHURA_LINK_GOTO_DEST, /**< Links to a page */
|
ZATHURA_LINK_GOTO_DEST, /**< Links to a page */
|
||||||
ZATHURA_LINK_GOTO_REMOTE, /**< Links to a page */
|
ZATHURA_LINK_GOTO_REMOTE, /**< Links to a page */
|
||||||
ZATHURA_LINK_URI, /**< Links to an external source */
|
ZATHURA_LINK_URI, /**< Links to an external source */
|
||||||
|
@ -158,15 +158,15 @@ typedef enum zathura_link_type_e
|
||||||
|
|
||||||
typedef enum zathura_link_destination_type_e
|
typedef enum zathura_link_destination_type_e
|
||||||
{
|
{
|
||||||
ZATHURA_LINK_DESTINATION_UNKNOWN,
|
ZATHURA_LINK_DESTINATION_UNKNOWN,
|
||||||
ZATHURA_LINK_DESTINATION_XYZ,
|
ZATHURA_LINK_DESTINATION_XYZ,
|
||||||
ZATHURA_LINK_DESTINATION_FIT,
|
ZATHURA_LINK_DESTINATION_FIT,
|
||||||
ZATHURA_LINK_DESTINATION_FITH,
|
ZATHURA_LINK_DESTINATION_FITH,
|
||||||
ZATHURA_LINK_DESTINATION_FITV,
|
ZATHURA_LINK_DESTINATION_FITV,
|
||||||
ZATHURA_LINK_DESTINATION_FITR,
|
ZATHURA_LINK_DESTINATION_FITR,
|
||||||
ZATHURA_LINK_DESTINATION_FITB,
|
ZATHURA_LINK_DESTINATION_FITB,
|
||||||
ZATHURA_LINK_DESTINATION_FITBH,
|
ZATHURA_LINK_DESTINATION_FITBH,
|
||||||
ZATHURA_LINK_DESTINATION_FITBV
|
ZATHURA_LINK_DESTINATION_FITBV
|
||||||
} zathura_link_destination_type_t;
|
} zathura_link_destination_type_t;
|
||||||
|
|
||||||
typedef struct zathura_link_target_s
|
typedef struct zathura_link_target_s
|
||||||
|
@ -255,4 +255,9 @@ zathura_document_information_entry_new(zathura_document_information_type_t
|
||||||
*/
|
*/
|
||||||
void zathura_document_information_entry_free(zathura_document_information_entry_t* entry);
|
void zathura_document_information_entry_free(zathura_document_information_entry_t* entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context for MIME type detection
|
||||||
|
*/
|
||||||
|
typedef struct zathura_content_type_context_s zathura_content_type_context_t;
|
||||||
|
|
||||||
#endif // TYPES_H
|
#endif // TYPES_H
|
||||||
|
|
|
@ -52,12 +52,14 @@ file_valid_extension(zathura_t* zathura, const char* path)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar* content_type = guess_content_type(path);
|
const gchar* content_type =
|
||||||
|
zathura_content_type_guess(zathura->content_type_context, path);
|
||||||
if (content_type == NULL) {
|
if (content_type == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
zathura_plugin_t* plugin = zathura_plugin_manager_get_plugin(zathura->plugins.manager, content_type);
|
zathura_plugin_t* plugin =
|
||||||
|
zathura_plugin_manager_get_plugin(zathura->plugins.manager, content_type);
|
||||||
g_free((void*)content_type);
|
g_free((void*)content_type);
|
||||||
|
|
||||||
return (plugin == NULL) ? false : true;
|
return (plugin == NULL) ? false : true;
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "dbus-interface.h"
|
#include "dbus-interface.h"
|
||||||
#include "css-definitions.h"
|
#include "css-definitions.h"
|
||||||
#include "synctex.h"
|
#include "synctex.h"
|
||||||
|
#include "content-type.h"
|
||||||
|
|
||||||
typedef struct zathura_document_info_s {
|
typedef struct zathura_document_info_s {
|
||||||
zathura_t* zathura;
|
zathura_t* zathura;
|
||||||
|
@ -103,6 +104,9 @@ zathura_create(void)
|
||||||
zathura->signals.sigterm = g_unix_signal_add(SIGTERM, zathura_signal_sigterm, zathura);
|
zathura->signals.sigterm = g_unix_signal_add(SIGTERM, zathura_signal_sigterm, zathura);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* MIME type detection */
|
||||||
|
zathura->content_type_context = zathura_content_type_new();
|
||||||
|
|
||||||
zathura->ui.session->global.data = zathura;
|
zathura->ui.session->global.data = zathura;
|
||||||
|
|
||||||
return zathura;
|
return zathura;
|
||||||
|
@ -376,6 +380,9 @@ zathura_free(zathura_t* zathura)
|
||||||
|
|
||||||
document_close(zathura, false);
|
document_close(zathura, false);
|
||||||
|
|
||||||
|
/* MIME type detection */
|
||||||
|
zathura_content_type_free(zathura->content_type_context);
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
if (zathura->signals.sigterm > 0) {
|
if (zathura->signals.sigterm > 0) {
|
||||||
g_source_remove(zathura->signals.sigterm);
|
g_source_remove(zathura->signals.sigterm);
|
||||||
|
@ -760,7 +767,7 @@ document_open(zathura_t* zathura, const char* path, const char* uri, const char*
|
||||||
|
|
||||||
gchar* file_uri = NULL;
|
gchar* file_uri = NULL;
|
||||||
zathura_error_t error = ZATHURA_ERROR_OK;
|
zathura_error_t error = ZATHURA_ERROR_OK;
|
||||||
zathura_document_t* document = zathura_document_open(zathura->plugins.manager, path, uri, password, &error);
|
zathura_document_t* document = zathura_document_open(zathura, path, uri, password, &error);
|
||||||
|
|
||||||
if (document == NULL) {
|
if (document == NULL) {
|
||||||
if (error == ZATHURA_ERROR_INVALID_PASSWORD) {
|
if (error == ZATHURA_ERROR_INVALID_PASSWORD) {
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <girara/types.h>
|
#include <girara/types.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#ifdef GDK_WINDOWING_X11
|
||||||
#include <gtk/gtkx.h>
|
#include <gtk/gtkx.h>
|
||||||
|
#endif
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
@ -222,6 +224,11 @@ struct zathura_s
|
||||||
double zoom;
|
double zoom;
|
||||||
} toggle_presentation_mode;
|
} toggle_presentation_mode;
|
||||||
} shortcut;
|
} shortcut;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context for MIME type detection
|
||||||
|
*/
|
||||||
|
zathura_content_type_context_t* content_type_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue