diff options
author | Chris Maynard <Christopher.Maynard@GTECH.COM> | 2010-11-08 16:53:11 +0000 |
---|---|---|
committer | Chris Maynard <Christopher.Maynard@GTECH.COM> | 2010-11-08 16:53:11 +0000 |
commit | 803910c1aa72c56f2ff8d6fcb7dc1633c253b5aa (patch) | |
tree | ff48a1a5b0007909386fe212ce79bf4d1494bcc4 /gtk | |
parent | cab0cef11dbd45bf3f8fd212c5136ce59d95dd88 (diff) |
Allow objects to be saved that otherwise couldn't be due to invalid characters
in the filename, excessive filename lengths or duplicate filenames. Fixes
bug 1671.
svn path=/trunk/; revision=34805
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/export_object.c | 93 |
1 files changed, 90 insertions, 3 deletions
diff --git a/gtk/export_object.c b/gtk/export_object.c index ff4bbfab72..fd1b13c36d 100644 --- a/gtk/export_object.c +++ b/gtk/export_object.c @@ -53,6 +53,7 @@ #include <gtk/main.h> #include <gtk/stock_icons.h> #include "gtk/export_object.h" +#include <string.h> enum { EO_PKT_NUM_COLUMN, @@ -218,6 +219,78 @@ eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg) window_destroy(save_as_w); } +#define HINIBBLE(x) (((x) >> 4) & 0xf) +#define LONIBBLE(x) ((x) & 0xf) +#define HEXTOASCII(x) (((x) < 10) ? ((x) + '0') : ((x) - 10 + 'a')) +#define MAXFILELEN 255 + +static GString *eo_rename(GString *gstr, gchar dup) +{ + gchar tmp[4] = "( )"; + gchar *tmp_ptr; + GString *ext_str; + + tmp[1] = dup; + if ( (tmp_ptr = strrchr(gstr->str, '.')) != NULL ) { + /* Retain the extension */ + ext_str = g_string_new(tmp_ptr); + gstr = g_string_truncate(gstr, gstr->len - ext_str->len); + if ( gstr->len >= (MAXFILELEN - (strlen(tmp) + ext_str->len)) ) + gstr = g_string_truncate(gstr, MAXFILELEN - (strlen(tmp) + ext_str->len)); + gstr = g_string_append(gstr, tmp); + gstr = g_string_append(gstr, ext_str->str); + g_string_free(ext_str, TRUE); + } + else { + if ( gstr->len >= (MAXFILELEN - strlen(tmp)) ) + gstr = g_string_truncate(gstr, MAXFILELEN - strlen(tmp)); + gstr = g_string_append(gstr, tmp); + } + return gstr; +} + +static GString * +eo_massage_str(const gchar *in_str, guint maxlen, gchar dup) +{ + gchar *tmp_ptr; + /* The characters in "reject" come from: + * http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx. + * Add to the list as necessary for other OS's. + */ + const gchar *reject = "<>:\"/\\|?*" + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" + "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" + "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; + GString *out_str; + GString *ext_str; + + out_str = g_string_new(""); + + /* Find all disallowed characters/bytes and replace them with %xx */ + while ( (tmp_ptr = strpbrk(in_str, reject)) != NULL ) { + out_str = g_string_append_len(out_str, in_str, tmp_ptr - in_str); + out_str = g_string_append_c(out_str, '%'); + out_str = g_string_append_c(out_str, HEXTOASCII(HINIBBLE(*tmp_ptr))); + out_str = g_string_append_c(out_str, HEXTOASCII(LONIBBLE(*tmp_ptr))); + in_str = tmp_ptr + 1; + } + out_str = g_string_append(out_str, in_str); + if ( out_str->len > maxlen ) { + if ( (tmp_ptr = strrchr(out_str->str, '.')) != NULL ) { + /* Retain the extension */ + ext_str = g_string_new(tmp_ptr); + out_str = g_string_truncate(out_str, maxlen - ext_str->len); + out_str = g_string_append(out_str, ext_str->str); + g_string_free(ext_str, TRUE); + } + else + out_str = g_string_truncate(out_str, maxlen); + } + if ( dup != '0' ) + out_str = eo_rename(out_str, dup); + return out_str; +} + static void eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg) { @@ -227,6 +300,9 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg) GtkWidget *save_in_w; GSList *slist = object_list->entries; gboolean all_saved = TRUE; + gchar *save_in_path; + GString *safe_filename; + int count = 0; save_in_w = file_selection_new("Wireshark: Save All Objects In ...", FILE_SELECTION_CREATE_FOLDER); @@ -238,9 +314,20 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg) while(slist) { entry = slist->data; - save_as_fullpath = g_build_filename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_in_w)), entry->filename, NULL); - - if (!eo_save_entry(save_as_fullpath, entry, FALSE)) + save_in_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_in_w)); + if ( strlen(save_in_path) < MAXFILELEN ) { + do { + safe_filename = eo_massage_str(entry->filename, + MAXFILELEN - strlen(save_in_path), count | 0x30); + save_as_fullpath = g_build_filename( + save_in_path, safe_filename->str, NULL); + g_string_free(safe_filename, TRUE); + } while ( g_file_test(save_as_fullpath, G_FILE_TEST_EXISTS) && (++count < 10) ); + count = 0; + if (!eo_save_entry(save_as_fullpath, entry, TRUE)) + all_saved = FALSE; + } + else all_saved = FALSE; slist = slist->next; |