mirror of https://github.com/GNOME/gimp.git
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:
parent
c603af8f1b
commit
3408013740
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue