[nautilus-actions] Fix coredump when trying to import an empty file by DnD
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Fix coredump when trying to import an empty file by DnD
- Date: Tue, 6 Dec 2011 22:10:55 +0000 (UTC)
commit 90e837ee8201d89654b0ad81d35f4957af04a48e
Author: Pierre Wieser <pwieser trychlos org>
Date: Tue Dec 6 23:10:25 2011 +0100
Fix coredump when trying to import an empty file by DnD
ChangeLog | 16 +++++
po/POTFILES.in | 1 +
src/api/na-core-utils.h | 1 +
src/api/na-iimporter.h | 7 ++-
src/core/na-core-utils.c | 109 +++++++++++++++++++++++++++++++++++-
src/core/na-importer.c | 16 +++++-
src/io-desktop/nadp-desktop-file.c | 10 +++-
src/io-desktop/nadp-reader.c | 5 ++
src/io-xml/naxml-reader.c | 12 +++-
9 files changed, 168 insertions(+), 9 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8bab8df..047d678 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
2011-12-06 Pierre Wieser <pwieser trychlos org>
+ Fix a coredump when trying to import an empty file by DnD.
+ Extend the fix by checking the size and the type of the candidate.
+
+ * src/api/na-core-utils.h:
+ * src/core/na-core-utils.c (na_core_utils_file_is_loadable): New function.
+
+ * src/api/na-iimporter.h (IMPORTER_CODE_NOT_LOADABLE): New return code.
+
+ * src/core/na-importer.c (import_from_uri):
+ Do not try other modules one the first detects that a file is not loadable.
+
+ * src/io-desktop/nadp-desktop-file.c (nadp_desktop_file_new_from_uri):
+ * src/io-desktop/nadp-reader.c (nadp_reader_iimporter_import_from_uri):
+ * src/io-xml/naxml-reader.c (naxml_reader_import_from_uri):
+ Check whether the file is loadable before trying to import it.
+
* src/nact/nact-main-tab.h:
* src/nact/nact-main-window.h: Fix comments.
diff --git a/po/POTFILES.in b/po/POTFILES.in
index c9c099b..ba302fb 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,6 +4,7 @@ src/core/na-about.c
src/core/na-desktop-environment.c
src/core/na-icontext-factory.c
src/core/na-iimporter.c
+src/core/na-importer.c
src/core/na-importer-ask.c
[type: gettext/glade] src/core/na-importer-ask.ui
src/core/na-io-provider.c
diff --git a/src/api/na-core-utils.h b/src/api/na-core-utils.h
index 0167751..f9bbcb4 100644
--- a/src/api/na-core-utils.h
+++ b/src/api/na-core-utils.h
@@ -91,6 +91,7 @@ void na_core_utils_dir_split_ext( const gchar *string, gchar **first, gchar
*/
gboolean na_core_utils_file_delete ( const gchar *path );
gboolean na_core_utils_file_exists ( const gchar *uri );
+gboolean na_core_utils_file_is_loadable ( const gchar *uri );
gchar *na_core_utils_file_load_from_uri( const gchar *uri, gsize *length );
/* miscellaneous
diff --git a/src/api/na-iimporter.h b/src/api/na-iimporter.h
index a5f284b..81974d6 100644
--- a/src/api/na-iimporter.h
+++ b/src/api/na-iimporter.h
@@ -159,6 +159,10 @@ typedef enum {
* @IMPORTER_CODE_NO_ITEM_TYPE: item type not found.
* @IMPORTER_CODE_UNKNOWN_ITEM_TYPE: unknown item type.
* @IMPORTER_CODE_CANCELLED: operation cancelled by the user.
+ * @IMPORTER_CODE_NOT_LOADABLE: the file is considered as not loadable at all.
+ * This is not a matter of which I/O provider has been tried,
+ * but the file is empty, or too big, or eventually not a
+ * regular file.
*
* Define the return status of an import operation.
*/
@@ -169,7 +173,8 @@ typedef enum {
IMPORTER_CODE_NO_ITEM_ID,
IMPORTER_CODE_NO_ITEM_TYPE,
IMPORTER_CODE_UNKNOWN_ITEM_TYPE,
- IMPORTER_CODE_CANCELLED
+ IMPORTER_CODE_CANCELLED,
+ IMPORTER_CODE_NOT_LOADABLE
}
NAIImporterImportStatus;
diff --git a/src/core/na-core-utils.c b/src/core/na-core-utils.c
index 6277a1f..e71ea3b 100644
--- a/src/core/na-core-utils.c
+++ b/src/core/na-core-utils.c
@@ -43,8 +43,15 @@
#include "na-about.h"
+/* minimal and maximal size for loading the content of a file in memory
+ * used by na_core_utils_file_is_size_ok()
+ */
+#define SIZE_MIN 1
+#define SIZE_MAX 1048576 /* 1 MB */
+
static GSList *text_to_string_list( const gchar *text, const gchar *separator, const gchar *default_value );
static gboolean info_dir_is_writable( GFile *file, const gchar *path );
+static gboolean file_is_loadable( GFile *file );
/**
* na_core_utils_boolean_from_string
@@ -1002,6 +1009,92 @@ na_core_utils_file_exists( const gchar *uri )
}
/**
+ * na_core_utils_file_is_loadable:
+ * @uri: the URI to be checked.
+ *
+ * Checks that the file is suitable to be loaded in memory, because
+ * it is not empty, and its size is reasonable (less than 1MB).
+ * Also checks that a file is a regular file (or a symlink to a
+ * regular file).
+ *
+ * Returns: whether the file is suitable to be loaded in memory.
+ *
+ * Since: 3.1
+ */
+gboolean
+na_core_utils_file_is_loadable( const gchar *uri )
+{
+ static const gchar *thisfn = "na_core_utils_file_is_loadable";
+ GFile *file;
+ gboolean isok;
+
+ g_debug( "%s: uri=%s", thisfn, uri );
+
+ isok = FALSE;
+ file = g_file_new_for_uri( uri );
+
+ isok = file_is_loadable( file );
+
+ g_object_unref( file );
+
+ return( isok );
+}
+
+static gboolean
+file_is_loadable( GFile *file )
+{
+ static const gchar *thisfn = "na_core_utils_file_is_loadable";
+ GError *error;
+ GFileInfo *info;
+ guint64 size;
+ GFileType type;
+ gboolean isok;
+ GFile *target_file;
+
+ error = NULL;
+ isok = FALSE;
+ info = g_file_query_info( file,
+ G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ G_FILE_QUERY_INFO_NONE, NULL, &error );
+
+ if( !info ){
+ if( error ){
+ g_debug( "%s: %s", thisfn, error->message );
+ g_error_free( error );
+ }
+
+ } else {
+ size = g_file_info_get_attribute_uint64( info, G_FILE_ATTRIBUTE_STANDARD_SIZE );
+ g_debug( "%s: size=%lu", thisfn, ( unsigned long ) size );
+ isok = ( size >= SIZE_MIN && size <= SIZE_MAX );
+ }
+
+ if( isok ){
+ type = g_file_info_get_file_type( info );
+ g_debug( "%s: type=%u", thisfn, ( unsigned ) type );
+
+ if( type != G_FILE_TYPE_REGULAR ){
+ isok = FALSE;
+
+ if( type == G_FILE_TYPE_SYMBOLIC_LINK ){
+ const char *target = g_file_info_get_symlink_target( info );
+ if( target && strlen( target )){
+ target_file = g_file_resolve_relative_path( file, target );
+ if( target_file ){
+ isok = file_is_loadable( target_file );
+ g_object_unref( target_file );
+ }
+ }
+ }
+ }
+ }
+
+ g_object_unref( info );
+
+ return( isok );
+}
+
+/**
* na_core_utils_file_load_from_uri:
* @uri: the URI the file must be loaded from.
* @length: a pointer to the length of the read content.
@@ -1017,17 +1110,31 @@ na_core_utils_file_exists( const gchar *uri )
gchar *
na_core_utils_file_load_from_uri( const gchar *uri, gsize *length )
{
+ static const gchar *thisfn = "na_core_utils_file_load_from_uri";
gchar *data;
GFile *file;
+ GError *error;
+
+ g_debug( "%s: uri=%s, length=%p", thisfn, uri, ( void * ) length );
+
+ error = NULL;
+ data = NULL;
+ if( length ){
+ *length = 0;
+ }
file = g_file_new_for_uri( uri );
- if( !g_file_load_contents( file, NULL, &data, length, NULL, NULL )){
+ if( !g_file_load_contents( file, NULL, &data, length, NULL, &error )){
g_free( data );
data = NULL;
if( length ){
*length = 0;
}
+ if( error ){
+ g_debug( "%s: %s", thisfn, error->message );
+ g_error_free( error );
+ }
}
g_object_unref( file );
diff --git a/src/core/na-importer.c b/src/core/na-importer.c
index 8c23938..0bebb9e 100644
--- a/src/core/na-importer.c
+++ b/src/core/na-importer.c
@@ -32,6 +32,7 @@
#include <config.h>
#endif
+#include <glib/gi18n.h>
#include <string.h>
#include <api/na-core-utils.h>
@@ -55,6 +56,9 @@ static guint import_from_uri( const NAPivot *pivot, GList *modules, NAIm
static NAObjectItem *is_importing_already_exists( const NAObjectItem *importing, ImporterExistsStr *parms );
static guint ask_user_for_mode( const NAObjectItem *importing, const NAObjectItem *existing, NAImporterAskUserParms *parms );
+/* i18n: '%s' stands for the file URI */
+#define ERR_NOT_LOADABLE _( "%s is not loadable (empty or too big or not a regular file)" )
+
/*
* na_importer_import_from_list:
* @pivot: the #NAPivot pivot for this application.
@@ -177,13 +181,23 @@ import_from_uri( const NAPivot *pivot, GList *modules, NAImporterParms *parms, c
all_messages = NULL;
- for( im = modules ; im && code == IMPORTER_CODE_NOT_WILLING_TO ; im = im->next ){
+ for( im = modules ;
+ im && ( code == IMPORTER_CODE_NOT_WILLING_TO || code == IMPORTER_CODE_NOT_LOADABLE ) ;
+ im = im->next ){
+
code = na_iimporter_import_from_uri( NA_IIMPORTER( im->data ), &provider_parms );
if( code == IMPORTER_CODE_NOT_WILLING_TO ){
all_messages = g_slist_concat( all_messages, provider_parms.messages );
provider_parms.messages = NULL;
+ } else if( code == IMPORTER_CODE_NOT_LOADABLE ){
+ na_core_utils_slist_free( all_messages );
+ all_messages = NULL;
+ na_core_utils_slist_free( provider_parms.messages );
+ provider_parms.messages = NULL;
+ na_core_utils_slist_add_message( &all_messages, ERR_NOT_LOADABLE, ( const gchar * ) uri );
+
} else {
na_core_utils_slist_free( all_messages );
all_messages = provider_parms.messages;
diff --git a/src/io-desktop/nadp-desktop-file.c b/src/io-desktop/nadp-desktop-file.c
index 50d83c0..411b454 100644
--- a/src/io-desktop/nadp-desktop-file.c
+++ b/src/io-desktop/nadp-desktop-file.c
@@ -279,12 +279,18 @@ nadp_desktop_file_new_from_uri( const gchar *uri )
gsize length;
ndf = NULL;
+ data = NULL;
+ length = 0;
+
g_debug( "%s: uri=%s", thisfn, uri );
g_return_val_if_fail( uri && g_utf8_strlen( uri, -1 ), ndf );
data = na_core_utils_file_load_from_uri( uri, &length );
- if( !length ){
- g_debug( "%s: file is empty", thisfn );
+ g_debug( "%s: length=%lu", thisfn, ( unsigned long ) length );
+
+ /* normally, length and data should be both NULL or both not NULL
+ */
+ if( !length || !data ){
return( NULL );
}
diff --git a/src/io-desktop/nadp-reader.c b/src/io-desktop/nadp-reader.c
index b2d99fb..2d26c69 100644
--- a/src/io-desktop/nadp-reader.c
+++ b/src/io-desktop/nadp-reader.c
@@ -368,6 +368,11 @@ nadp_reader_iimporter_import_from_uri( const NAIImporter *instance, NAIImporterI
g_return_val_if_fail( NA_IS_IIMPORTER( instance ), IMPORTER_CODE_PROGRAM_ERROR );
g_return_val_if_fail( NADP_IS_DESKTOP_PROVIDER( instance ), IMPORTER_CODE_PROGRAM_ERROR );
+ if( !na_core_utils_file_is_loadable( parms->uri )){
+ code = IMPORTER_CODE_NOT_LOADABLE;
+ return( code );
+ }
+
code = IMPORTER_CODE_NOT_WILLING_TO;
ndf = nadp_desktop_file_new_from_uri( parms->uri );
diff --git a/src/io-xml/naxml-reader.c b/src/io-xml/naxml-reader.c
index a07d060..d3f51db 100644
--- a/src/io-xml/naxml-reader.c
+++ b/src/io-xml/naxml-reader.c
@@ -329,14 +329,18 @@ naxml_reader_import_from_uri( const NAIImporter *instance, NAIImporterImportFrom
g_return_val_if_fail( NA_IS_IIMPORTER( instance ), IMPORTER_CODE_PROGRAM_ERROR );
- reader = reader_new();
- reader->private->importer = ( NAIImporter * ) instance;
- reader->private->parms = parms;
-
parms->exist = FALSE;
parms->import_mode = IMPORTER_MODE_NO_IMPORT;
parms->imported = NULL;
+ if( !na_core_utils_file_is_loadable( parms->uri )){
+ return( IMPORTER_CODE_NOT_LOADABLE );
+ }
+
+ reader = reader_new();
+ reader->private->importer = ( NAIImporter * ) instance;
+ reader->private->parms = parms;
+
code = reader_parse_xmldoc( reader );
if( code == IMPORTER_CODE_NOT_WILLING_TO ){
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]