[libgxps] Fixed crash in gxps_file_new()
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgxps] Fixed crash in gxps_file_new()
- Date: Tue, 2 Aug 2011 13:11:29 +0000 (UTC)
commit d4bb8cede704e7e35c4c7339aff46ffbbd98a852
Author: Jason Crain <jason aquaticape us>
Date: Tue Aug 2 00:15:47 2011 -0500
Fixed crash in gxps_file_new()
gxps_file_new() crashes when passed a directory or a nonexistant
file.
libgxps/gxps-archive.c | 96 +++++++++++++++++++++++++++++++++++++++++++-----
libgxps/gxps-archive.h | 3 +-
libgxps/gxps-file.c | 6 ++-
3 files changed, 93 insertions(+), 12 deletions(-)
---
diff --git a/libgxps/gxps-archive.c b/libgxps/gxps-archive.c
index 1508e51..b63efe2 100644
--- a/libgxps/gxps-archive.c
+++ b/libgxps/gxps-archive.c
@@ -25,18 +25,28 @@
#include "gxps-archive.h"
+enum {
+ PROP_0,
+ PROP_FILE
+};
+
struct _GXPSArchive {
GObject parent;
- GFile *filename;
- GList *entries;
+ gboolean initialized;
+ GError *init_error;
+ GFile *filename;
+ GList *entries;
};
struct _GXPSArchiveClass {
GObjectClass parent_class;
};
-G_DEFINE_TYPE (GXPSArchive, gxps_archive, G_TYPE_OBJECT)
+static void initable_iface_init (GInitableIface *initable_iface);
+
+G_DEFINE_TYPE_WITH_CODE (GXPSArchive, gxps_archive, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init))
#define BUFFER_SIZE 4096
@@ -112,7 +122,8 @@ _archive_close (struct archive *archive,
{
ZipArchive *zip = (ZipArchive *)data;
- g_object_unref (zip->stream);
+ if (zip->stream)
+ g_object_unref (zip->stream);
zip->stream = NULL;
return ARCHIVE_OK;
@@ -159,6 +170,8 @@ gxps_archive_finalize (GObject *object)
archive->filename = NULL;
}
+ g_clear_error (&archive->init_error);
+
G_OBJECT_CLASS (gxps_archive_parent_class)->finalize (object);
}
@@ -169,25 +182,72 @@ gxps_archive_init (GXPSArchive *archive)
}
static void
+gxps_archive_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GXPSArchive *archive = GXPS_ARCHIVE (object);
+
+ switch (prop_id) {
+ case PROP_FILE:
+ archive->filename = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
gxps_archive_class_init (GXPSArchiveClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->set_property = gxps_archive_set_property;
object_class->finalize = gxps_archive_finalize;
+
+ g_object_class_install_property (object_class,
+ PROP_FILE,
+ g_param_spec_object ("file",
+ "File",
+ "The archive file",
+ G_TYPE_FILE,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
}
-GXPSArchive *
-gxps_archive_new (GFile *filename)
+static gboolean
+gxps_archive_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
{
GXPSArchive *archive;
ZipArchive *zip;
struct archive_entry *entry;
gint result;
- archive = GXPS_ARCHIVE (g_object_new (GXPS_TYPE_ARCHIVE, NULL));
- archive->filename = g_object_ref (filename);
+ archive = GXPS_ARCHIVE (initable);
+
+ if (archive->initialized) {
+ if (archive->init_error) {
+ g_propagate_error (error, g_error_copy (archive->init_error));
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ archive->initialized = TRUE;
+
+ zip = gxps_zip_archive_create (archive->filename);
+ if (zip->error) {
+ g_propagate_error (&archive->init_error, zip->error);
+ g_propagate_error (error, g_error_copy (archive->init_error));
+ gxps_zip_archive_destroy (zip);
+ return FALSE;
+ }
- zip = gxps_zip_archive_create (filename);
do {
result = archive_read_next_header (zip->archive, &entry);
if (result >= ARCHIVE_WARN && result <= ARCHIVE_OK) {
@@ -205,7 +265,23 @@ gxps_archive_new (GFile *filename)
gxps_zip_archive_destroy (zip);
- return archive;
+ return TRUE;
+}
+
+static void
+initable_iface_init (GInitableIface *initable_iface)
+{
+ initable_iface->init = gxps_archive_initable_init;
+}
+
+GXPSArchive *
+gxps_archive_new (GFile *filename,
+ GError **error)
+{
+ return g_initable_new (GXPS_TYPE_ARCHIVE,
+ NULL, error,
+ "file", filename,
+ NULL);
}
gboolean
diff --git a/libgxps/gxps-archive.h b/libgxps/gxps-archive.h
index 05edc6b..62226db 100644
--- a/libgxps/gxps-archive.h
+++ b/libgxps/gxps-archive.h
@@ -38,7 +38,8 @@ typedef struct _GXPSArchiveClass GXPSArchiveClass;
typedef struct _GXPSArchiveEntry GXPSArchiveEntry;
GType gxps_archive_get_type (void) G_GNUC_CONST;
-GXPSArchive *gxps_archive_new (GFile *filename);
+GXPSArchive *gxps_archive_new (GFile *filename,
+ GError **error);
gboolean gxps_archive_has_entry (GXPSArchive *archive,
const gchar *path);
diff --git a/libgxps/gxps-file.c b/libgxps/gxps-file.c
index 02af1b2..10002e6 100644
--- a/libgxps/gxps-file.c
+++ b/libgxps/gxps-file.c
@@ -316,7 +316,11 @@ gxps_file_initable_init (GInitable *initable,
xps->priv->initialized = TRUE;
- xps->priv->zip = gxps_archive_new (xps->priv->file);
+ xps->priv->zip = gxps_archive_new (xps->priv->file, &xps->priv->init_error);
+ if (!xps->priv->zip) {
+ g_propagate_error (error, g_error_copy (xps->priv->init_error));
+ return FALSE;
+ }
if (!gxps_file_parse_rels (xps, &xps->priv->init_error)) {
g_propagate_error (error, g_error_copy (xps->priv->init_error));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]