[Usability] [gnome-terminal] escaping special characters on dnd



Hello, I am new here, and unsure as to whether this is the right list
to post this to?  I have a feature request, and a trivial patch which
implements it.

In gnome-terminal, for anyone who does not already use this feature,
when a user drags something into a terminal window, the URI is copied
into the terminal.  Local filenames are even converted from full
"file://" URIs to simple path names.  This is a really cool feature.

However, many filenames in the wild have evil characters such as
!#&*()[]{}"'`<>,; and whitespace.  If, for example, you were to
download a .torrent from mininova.org, and then type 'azureus ' into
the terminal and try to drag and drop the filename, bash would
complain about the characters in that filename.

The solution is to escape those characters before inserting the
filename.  Attached is a patch to do this.

Potential bugs-
This may or may not be the right list of special characters for other
shells than bash.  It might not even be complete for bash itself.
This is obviously wrong if bash is not the program recieving input.  I
don't know to to see if a shell is recieving input, however.

~thomas
--
cartwheel ^(^_^)> v(.-.)v <(^_^)^
Index: terminal-screen.c
===================================================================
RCS file: /cvs/gnome/gnome-terminal/src/terminal-screen.c,v
retrieving revision 1.126
diff -u -p -r1.126 terminal-screen.c
--- terminal-screen.c	24 Jul 2006 22:05:37 -0000	1.126
+++ terminal-screen.c	30 Jul 2006 19:20:06 -0000
@@ -2432,22 +2432,110 @@ drag_data_received  (GtkWidget *widget, 
 	uris = g_strsplit (uri_list, "\r\n", 0);
 
         i = 0;
-        while (uris && uris[i])
+	while (uris && uris[i])
           {
             char *old;
             
             old = uris[i];
-
+	    /* First, treat the dropped URI like it's a filename */
             uris[i] = g_filename_from_uri (old, NULL, NULL);
+	    /* if it's NULL, that means it wasn't a filename.
+	     * Pass it as a plain URI, then.
+	     */
+	    if (uris[i] == NULL)
+	      uris[i] = old;
+	    /* Otherwise, it's a file.  Now then.  If it has any special
+	     * characters, we must quote them.  One way to do this is to put
+	     * backslashes ('\') in front of these characters- 
+	     * !#&*()[]{}"'`|\<>,
+	     * -and, of course, whitespace.  Probably, there are others I'm
+	     * forgetting.
+	     * My algorithm is similar to that in g_strescape().
+	     */
+            else 
+	      {
+		gchar *cur;
+		GString *new;
 
-            /* If the URI wasn't a filename, then pass it through
-             * as a URI, so you can DND from Mozilla or whatever
-             */
-            if (uris[i] == NULL)
-              uris[i] = old;
-            else
-              g_free (old);
-            
+		new = g_string_sized_new(strlen(uris[i]));
+		for(cur = uris[i]; *cur != '\0'; cur++)
+		  {
+		    switch(*cur)
+		      {
+		      case ' ':
+			g_string_append(new, "\\ ");
+			break;
+		      case '\n':
+			g_string_append(new, "\\\n");
+			break;
+		      case '\t':
+			g_string_append(new, "\\\t");
+			break;
+		      case '!':
+			g_string_append(new, "\\!");
+			break;
+		      case '#':
+			g_string_append(new, "\\#");
+			break;
+		      case '&':
+			g_string_append(new, "\\&");
+			break;
+		      case '*':
+			g_string_append(new, "\\*");
+			break;
+		      case '(':
+			g_string_append(new, "\\(");
+			break;
+		      case ')':
+			g_string_append(new, "\\)");
+			break;
+		      case '[':
+			g_string_append(new, "\\[");
+			break;
+		      case ']':
+			g_string_append(new, "\\]");
+			break;
+		      case '{':
+			g_string_append(new, "\\{");
+			break;
+		      case '}':
+			g_string_append(new, "\\}");
+			break;
+		      case '\"':
+			g_string_append(new, "\\\"");
+			break;
+		      case '\'':
+			g_string_append(new, "\\\'");
+			break;
+		      case '`':
+			g_string_append(new, "\\`");
+			break;
+		      case '|':
+			g_string_append(new, "\\|");
+			break;
+		      case '\\':
+			g_string_append(new, "\\\\");
+			break;
+		      case '<':
+			g_string_append(new, "\\<");
+			break;
+		      case '>':
+			g_string_append(new, "\\>");
+			break;
+		      case ',':
+			g_string_append(new, "\\,");
+			break;
+		      case ';':
+			g_string_append(new, "\\;");
+			break;
+		      default:
+			g_string_append_c(new, *cur);
+		      }
+		  }
+		g_free(uris[i]);
+		uris[i] = new->str;
+		g_string_free(new, 0);
+	      }
             ++i;
           }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]