[nautilus-actions] Better quote filenames and URIs



commit 39ae0b15ade005bebd03f05fb3bcdee40a70d365
Author: Pierre Wieser <pwieser trychlos org>
Date:   Tue Jan 4 22:07:13 2011 +0100

    Better quote filenames and URIs

 ChangeLog                   |    8 +++++
 src/core/na-selected-info.c |   67 +++++++++++++++++++++++++++++++++++++++++--
 src/core/na-tokens.c        |   28 ++++++------------
 3 files changed, 81 insertions(+), 22 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index f310169..70be84e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2011-01-04 Pierre Wieser <pwieser trychlos org>
 
+	* src/core/na-selected-info.c (new_from_uri):
+	- Add an excerpt from RFC 2396 about valid characters in URIs.
+	- Prefer the filename from g_filename_from_uri() when possible.
+
+	* src/core/na-tokens.c
+	(na_tokens_new_from_selection): Also g_shell_quote() the URI to preserve quotes.
+	(build_string_lists_item): Removed function.
+
 	* src/core/na-iabout.c (na_iabout_display):
 	Fix typo in comment, adding a note to the translators.
 
diff --git a/src/core/na-selected-info.c b/src/core/na-selected-info.c
index 8f0b7f9..2e051ae 100644
--- a/src/core/na-selected-info.c
+++ b/src/core/na-selected-info.c
@@ -702,14 +702,66 @@ new_from_nautilus_file_info( NautilusFileInfo *item )
  * Nautilus uses to address the desktop via the 'x-nautilus-desktop:///' URI.
  * g_filename_from_uri() complains that
  * "The URI 'x-nautilus-desktop:///' is not an absolute URI using the "file" scheme".
- * We so prefer the vfs->path member wich is just a decomposition of the URI,
- * and does not try to interpret it.
+ * In this case, we prefer the vfs->path member wich is just a decomposition of the
+ * URI, and does not try to interpret it.
+ *
+ * *********************************************************************************
+ * Extract from RFC 2396:
+ *
+ * 2.4.3. Excluded US-ASCII Characters
+ *
+ * Although they are disallowed within the URI syntax, we include here a
+ * description of those US-ASCII characters that have been excluded and
+ * the reasons for their exclusion.
+ *
+ * The control characters in the US-ASCII coded character set are not
+ * used within a URI, both because they are non-printable and because
+ * they are likely to be misinterpreted by some control mechanisms.
+ *
+ * control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
+ *
+ * The space character is excluded because significant spaces may
+ * disappear and insignificant spaces may be introduced when URI are
+ * transcribed or typeset or subjected to the treatment of word-
+ * processing programs. Whitespace is also used to delimit URI in many
+ * contexts.
+ *
+ * space = <US-ASCII coded character 20 hexadecimal>
+ *
+ * The angle-bracket "<" and ">" and double-quote (") characters are
+ * excluded because they are often used as the delimiters around URI in
+ * text documents and protocol fields. The character "#" is excluded
+ * because it is used to delimit a URI from a fragment identifier in URI
+ * references (Section 4). The percent character "%" is excluded because
+ * it is used for the encoding of escaped characters.
+ *
+ * delims = "<" | ">" | "#" | "%" | <">
+ *
+ * Other characters are excluded because gateways and other transport
+ * agents are known to sometimes modify such characters, or they are
+ * used as delimiters.
+ *
+ * unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
+ *
+ * Data corresponding to excluded characters must be escaped in order to
+ * be properly represented within a URI.
+ *
+ * pwi 2011-01-04:
+ *
+ * It results from the above excerpt that:
+ * - as double quotes are not valid character in URI, they have to be
+ *   escaped as %22, and so Nautilus does
+ * - but simple quotes are not forbidden, and so have not to be
+ *   escaped, and so Nautilus does not escape them
+ *
+ * As a result, we may have valid, non-escaped, simple quotes in an URI.
  */
 static NASelectedInfo *
 new_from_uri( const gchar *uri, const gchar *mimetype, gchar **errmsg )
 {
 	GFile *location;
 	NAGnomeVFSURI *vfs;
+	GError *error;
 
 	NASelectedInfo *info = g_object_new( NA_SELECTED_INFO_TYPE, NULL );
 
@@ -720,7 +772,16 @@ new_from_uri( const gchar *uri, const gchar *mimetype, gchar **errmsg )
 
 	vfs = g_new0( NAGnomeVFSURI, 1 );
 	na_gnome_vfs_uri_parse( vfs, uri );
-	info->private->filename = g_strdup( vfs->path );
+	error = NULL;
+	info->private->filename = g_filename_from_uri( uri, NULL, &error );
+	if( error ){
+		g_debug( "new_from_uri: uri='%s', error=%s", uri, error->message );
+		g_error_free( error );
+	}
+	if( !info->private->filename ){
+		g_debug( "new_from_uri: uri='%s', filename=NULL, setting it to '%s'", uri, vfs->path );
+		info->private->filename = g_strdup( vfs->path );
+	}
 	info->private->dirname = g_path_get_dirname( info->private->filename );
 	info->private->basename = g_path_get_basename( info->private->filename );
 	info->private->hostname = g_strdup( vfs->host_name );
diff --git a/src/core/na-tokens.c b/src/core/na-tokens.c
index fba6bbc..d2ad00b 100644
--- a/src/core/na-tokens.c
+++ b/src/core/na-tokens.c
@@ -85,7 +85,6 @@ static void      instance_dispose( GObject *object );
 static void      instance_finalize( GObject *object );
 
 static NATokens *build_string_lists( NATokens *tokens );
-static gchar    *build_string_lists_item( GSList **pslist );
 static void      execute_action_command( const gchar *command, const NAObjectProfile *profile );
 static gboolean  is_singular_exec( const NATokens *tokens, const gchar *exec );
 static gchar    *parse_singular( const NATokens *tokens, const gchar *input, guint i, gboolean utf8 );
@@ -340,7 +339,8 @@ na_tokens_new_from_selection( GList *selection )
 			first = FALSE;
 		}
 
-		tokens->private->uris = g_slist_prepend( tokens->private->uris, uri );
+		/* even an URI has to be quoted in order to preserve simple quotes */
+		tokens->private->uris = g_slist_prepend( tokens->private->uris, g_shell_quote( uri ));
 
 		tokens->private->filenames = g_slist_prepend( tokens->private->filenames, g_shell_quote( filename ));
 		tokens->private->basedirs = g_slist_prepend( tokens->private->basedirs, g_shell_quote( basedir ));
@@ -419,27 +419,17 @@ na_tokens_execute_action( const NATokens *tokens, const NAObjectProfile *profile
 static NATokens *
 build_string_lists( NATokens *tokens )
 {
-	tokens->private->uris_str            = build_string_lists_item( &tokens->private->uris );
-	tokens->private->filenames_str       = build_string_lists_item( &tokens->private->filenames );
-	tokens->private->basedirs_str        = build_string_lists_item( &tokens->private->basedirs );
-	tokens->private->basenames_str       = build_string_lists_item( &tokens->private->basenames );
-	tokens->private->basenames_woext_str = build_string_lists_item( &tokens->private->basenames_woext );
-	tokens->private->exts_str            = build_string_lists_item( &tokens->private->exts );
-	tokens->private->mimetypes_str       = build_string_lists_item( &tokens->private->mimetypes );
+	tokens->private->uris_str            = na_core_utils_slist_join_at_end( g_slist_reverse( tokens->private->uris ), " " );
+	tokens->private->filenames_str       = na_core_utils_slist_join_at_end( g_slist_reverse( tokens->private->filenames ), " " );
+	tokens->private->basedirs_str        = na_core_utils_slist_join_at_end( g_slist_reverse( tokens->private->basedirs ), " " );
+	tokens->private->basenames_str       = na_core_utils_slist_join_at_end( g_slist_reverse( tokens->private->basenames ), " " );
+	tokens->private->basenames_woext_str = na_core_utils_slist_join_at_end( g_slist_reverse( tokens->private->basenames_woext ), " " );
+	tokens->private->exts_str            = na_core_utils_slist_join_at_end( g_slist_reverse( tokens->private->exts ), " " );
+	tokens->private->mimetypes_str       = na_core_utils_slist_join_at_end( g_slist_reverse( tokens->private->mimetypes ), " " );
 
 	return( tokens );
 }
 
-static gchar *
-build_string_lists_item( GSList **pslist )
-{
-	*pslist = g_slist_reverse( *pslist );
-
-	gchar *str = na_core_utils_slist_join_at_end( *pslist, " " );
-
-	return( str );
-}
-
 static void
 execute_action_command( const gchar *command, const NAObjectProfile *profile )
 {



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