slightly better error handling; doesn't address bug #358203 yet.

2006-10-06  Sven Neumann  <sven@gimp.org>

	* app/dialogs/file-open-location-dialog.c
	(file_open_location_response): slightly better error handling;
	doesn't address bug #358203 yet.

	* app/file/file-utils.c (file_check_single_magic)
	(file_check_magic_list): code cleanup.
This commit is contained in:
Sven Neumann 2006-10-06 12:31:15 +00:00 committed by Sven Neumann
parent c603af8f1b
commit 3408013740
3 changed files with 120 additions and 80 deletions

View File

@ -1,3 +1,12 @@
2006-10-06 Sven Neumann <sven@gimp.org>
* app/dialogs/file-open-location-dialog.c
(file_open_location_response): slightly better error handling;
doesn't address bug #358203 yet.
* app/file/file-utils.c (file_check_single_magic)
(file_check_magic_list): code cleanup.
2006-10-06 Sven Neumann <sven@gimp.org>
* plug-ins/FractalExplorer/Dialogs.c: changed some labels to be

View File

@ -174,49 +174,61 @@ file_open_location_response (GtkDialog *dialog,
gchar *uri;
gchar *filename;
gchar *hostname;
GError *error = NULL;
GError *error = NULL;
GimpPDBStatusType status;
filename = g_filename_from_uri (text, &hostname, NULL);
if (filename)
{
uri = g_filename_to_uri (filename, hostname, NULL);
uri = g_filename_to_uri (filename, hostname, &error);
g_free (hostname);
g_free (filename);
}
else
{
uri = file_utils_filename_to_uri (gimp->plug_in_manager->load_procs,
text, NULL);
text, &error);
}
box = gimp_progress_box_new ();
gtk_container_set_border_width (GTK_CONTAINER (box), 12);
gtk_box_pack_end (GTK_BOX (dialog->vbox), box, FALSE, FALSE, 0);
gtk_widget_show (box);
g_object_set_data (G_OBJECT (dialog), "progress-box", box);
image = file_open_with_proc_and_display (gimp,
gimp_get_user_context (gimp),
GIMP_PROGRESS (box),
uri, text, NULL,
&status, &error);
if (image == NULL && status != GIMP_PDB_CANCEL)
if (uri)
{
gchar *filename = file_utils_uri_display_name (uri);
gtk_widget_show (box);
image = file_open_with_proc_and_display (gimp,
gimp_get_user_context (gimp),
GIMP_PROGRESS (box),
uri, text, NULL,
&status, &error);
if (image == NULL && status != GIMP_PDB_CANCEL)
{
gchar *filename = file_utils_uri_display_name (uri);
gimp_message (gimp, GIMP_PROGRESS (box),
_("Opening '%s' failed:\n\n%s"),
filename, error->message);
g_clear_error (&error);
g_free (filename);
}
g_free (uri);
}
else
{
gimp_message (gimp, GIMP_PROGRESS (box),
_("Opening '%s' failed:\n\n%s"),
filename, error->message);
text, error->message);
g_clear_error (&error);
g_free (filename);
}
g_free (uri);
}
gtk_widget_destroy (GTK_WIDGET (dialog));

View File

@ -57,6 +57,14 @@
#include "gimp-intl.h"
typedef enum
{
FILE_MATCH_NONE,
FILE_MATCH_MAGIC,
FILE_MATCH_SIZE
} FileMatchType;
/* local function prototypes */
static GimpPlugInProcedure * file_proc_find_by_prefix (GSList *procs,
@ -78,13 +86,13 @@ static void file_convert_string (const gchar *instr,
gchar *outmem,
gint maxmem,
gint *nmem);
static gint file_check_single_magic (const gchar *offset,
static FileMatchType file_check_single_magic (const gchar *offset,
const gchar *type,
const gchar *value,
const guchar *file_head,
gint headsize,
FILE *ifp);
static gint file_check_magic_list (GSList *magics_list,
static FileMatchType file_check_magic_list (GSList *magics_list,
const guchar *head,
gint headsize,
FILE *ifp);
@ -213,7 +221,7 @@ file_utils_find_proc (GSList *procs,
FILE *ifp = NULL;
gint head_size = -2;
gint size_match_count = 0;
gint match_val;
FileMatchType match_val;
guchar head[256];
while (procs)
@ -520,7 +528,7 @@ file_proc_find_by_prefix (GSList *procs,
prefixes;
prefixes = g_slist_next (prefixes))
{
if (strncmp (uri, prefixes->data, strlen (prefixes->data)) == 0)
if (g_str_has_prefix (uri, prefixes->data))
return proc;
}
}
@ -726,7 +734,7 @@ file_convert_string (const gchar *instr,
*nmem = ((gchar *) uout) - outmem;
}
static gint
static FileMatchType
file_check_single_magic (const gchar *offset,
const gchar *type,
const gchar *value,
@ -735,43 +743,41 @@ file_check_single_magic (const gchar *offset,
FILE *ifp)
{
/* Return values are 0: no match, 1: magic match, 2: size match */
FileMatchType found = FILE_MATCH_NONE;
glong offs;
gulong num_testval, num_operatorval;
gulong fileval;
gulong num_testval;
gulong num_operatorval;
gint numbytes, k;
gint c = 0;
gint found = 0;
const gchar *num_operator_ptr;
gchar num_operator;
gchar num_test;
gchar mem_testval[256];
/* Check offset */
if (sscanf (offset, "%ld", &offs) != 1) return (0);
if (offs < 0) return (0);
if (sscanf (offset, "%ld", &offs) != 1)
return FILE_MATCH_NONE;
if (offs < 0)
return FILE_MATCH_NONE;
/* Check type of test */
num_operator_ptr = NULL;
num_operator = '\0';
num_test = '=';
if (strncmp (type, "byte", 4) == 0)
if (g_str_has_prefix (type, "byte"))
{
numbytes = 1;
num_operator_ptr = type + 4;
num_operator_ptr = type + strlen ("byte");
}
else if (strncmp (type, "short", 5) == 0)
else if (g_str_has_prefix (type, "short"))
{
numbytes = 2;
num_operator_ptr = type + 5;
num_operator_ptr = type + strlen ("short");
}
else if (strncmp (type, "long", 4) == 0)
else if (g_str_has_prefix (type, "long"))
{
numbytes = 4;
num_operator_ptr = type + 4;
num_operator_ptr = type + strlen ("long");
}
else if (strncmp (type, "size", 4) == 0)
else if (g_str_has_prefix (type, "size"))
{
numbytes = 5;
}
@ -779,7 +785,10 @@ file_check_single_magic (const gchar *offset,
{
numbytes = 0;
}
else return (0);
else
{
return FILE_MATCH_NONE;
}
/* Check numerical operator value if present */
if (num_operator_ptr && (*num_operator_ptr == '&'))
@ -792,52 +801,57 @@ file_check_single_magic (const gchar *offset,
sscanf (num_operator_ptr+3, "%lx", &num_operatorval);
else /* octal */
sscanf (num_operator_ptr+2, "%lo", &num_operatorval);
num_operator = *num_operator_ptr;
}
}
if (numbytes > 0) /* Numerical test ? */
{
gchar num_test = '=';
gulong fileval = 0;
/* Check test value */
if ((value[0] == '=') || (value[0] == '>') || (value[0] == '<'))
{
num_test = value[0];
value++;
}
if (!g_ascii_isdigit (value[0])) return (0);
if ((value[0] == '>') || (value[0] == '<'))
{
num_test = value[0];
value++;
}
/*
* to anybody reading this: is strtol's parsing behaviour
* (e.g. "0x" prefix) broken on some systems or why do we
* do the base detection ourselves?
* */
if (value[0] != '0') /* decimal */
num_testval = strtol(value, NULL, 10);
else if (value[1] == 'x') /* hexadecimal */
num_testval = (unsigned long)strtoul(value+2, NULL, 16);
else /* octal */
num_testval = strtol(value+1, NULL, 8);
errno = 0;
num_testval = strtol (value, NULL, 0);
if (errno != 0)
return FILE_MATCH_NONE;
fileval = 0;
if (numbytes == 5) /* Check for file size ? */
{
struct stat buf;
if (fstat (fileno (ifp), &buf) < 0) return (0);
if (fstat (fileno (ifp), &buf) < 0)
return FILE_MATCH_NONE;
fileval = buf.st_size;
}
else if (offs + numbytes <= headsize) /* We have it in memory ? */
{
for (k = 0; k < numbytes; k++)
fileval = (fileval << 8) | (long)file_head[offs+k];
fileval = (fileval << 8) | (glong) file_head[offs+k];
}
else /* Read it from file */
{
if (fseek (ifp, offs, SEEK_SET) < 0) return (0);
gint c = 0;
if (fseek (ifp, offs, SEEK_SET) < 0)
return FILE_MATCH_NONE;
for (k = 0; k < numbytes; k++)
fileval = (fileval << 8) | (c = getc (ifp));
if (c == EOF) return (0);
if (c == EOF)
return FILE_MATCH_NONE;
}
if (num_operator == '&')
fileval &= num_operatorval;
@ -848,15 +862,19 @@ file_check_single_magic (const gchar *offset,
else
found = (fileval == num_testval);
if (found && (numbytes == 5)) found = 2;
if (found && (numbytes == 5))
found = FILE_MATCH_SIZE;
}
else if (numbytes == 0) /* String test */
{
gchar mem_testval[256];
file_convert_string (value,
mem_testval, sizeof (mem_testval),
&numbytes);
if (numbytes <= 0) return (0);
if (numbytes <= 0)
return FILE_MATCH_NONE;
if (offs + numbytes <= headsize) /* We have it in memory ? */
{
@ -864,12 +882,16 @@ file_check_single_magic (const gchar *offset,
}
else /* Read it from file */
{
if (fseek (ifp, offs, SEEK_SET) < 0) return (0);
found = 1;
if (fseek (ifp, offs, SEEK_SET) < 0)
return FILE_MATCH_NONE;
found = FILE_MATCH_MAGIC;
for (k = 0; found && (k < numbytes); k++)
{
c = getc (ifp);
found = (c != EOF) && (c == (int) mem_testval[k]);
gint c = getc (ifp);
found = (c != EOF) && (c == (gint) mem_testval[k]);
}
}
}
@ -877,22 +899,19 @@ file_check_single_magic (const gchar *offset,
return found;
}
/*
* Return values are 0: no match, 1: magic match, 2: size match
*/
static gint
static FileMatchType
file_check_magic_list (GSList *magics_list,
const guchar *head,
gint headsize,
FILE *ifp)
{
const gchar *offset;
const gchar *type;
const gchar *value;
gint and = 0;
gint found = 0;
gint match_val;
const gchar *offset;
const gchar *type;
const gchar *value;
gboolean and = FALSE;
FileMatchType found = FILE_MATCH_NONE;
FileMatchType match_val;
while (magics_list)
{
@ -914,9 +933,9 @@ file_check_magic_list (GSList *magics_list,
and = (strchr (offset, '&') != NULL);
if ((!and) && found)
if ((! and) && found)
return match_val;
}
return 0;
return FILE_MATCH_NONE;
}