Revision: 1574
http://geeqie.svn.sourceforge.net/geeqie/?rev=1574&view=rev
Author: zas_
Date: 2009-03-26 21:49:20 +0000 (Thu, 26 Mar 2009)
Log Message:
-----------
Improve editors through .desktop files implementation:
- stricter Exec parameters detection
- correct Icon key handling (absolute file vs name and --icon prefix)
- improved escape, single, double quotes handling and escaping
Modified Paths:
--------------
trunk/src/editors.c
Modified: trunk/src/editors.c
===================================================================
--- trunk/src/editors.c 2009-03-26 07:56:01 UTC (rev 1573)
+++ trunk/src/editors.c 2009-03-26 21:49:20 UTC (rev 1574)
@@ -144,6 +144,36 @@
return list;
}
+static gboolean editor_accepts_parameters(EditorDescription *editor)
+{
+ const gchar *p = editor->exec;
+
+ if (!p) return FALSE;
+
+ while (*p)
+ {
+ if (*p == '%' && p[1])
+ {
+ switch (p[1])
+ {
+ case 'F':
+ case 'f':
+ case 'U':
+ case 'u':
+ case 'i':
+ case 'k':
+ case 'c':
+ return TRUE;
+ default:
+ break;
+ }
+ }
+ p++;
+ }
+
+ return FALSE;
+}
+
static gboolean editor_read_desktop_file(const gchar *path)
{
GKeyFile *key_file;
@@ -256,12 +286,28 @@
editor->name = g_key_file_get_locale_string(key_file, DESKTOP_GROUP,
"Name", NULL, NULL);
editor->icon = g_key_file_get_string(key_file, DESKTOP_GROUP, "Icon",
NULL);
+
+ /* Icon key can be either a full path (absolute with file name
extension) or an icon name (without extension) */
+ if (editor->icon && !g_path_is_absolute(editor->icon))
+ {
+ gchar *ext = strrchr(editor->icon, '.');
+
+ if (ext && strlen(ext) == 4 &&
+ (!strcmp(ext, ".png") || !strcmp(ext, ".xpm") ||
!strcmp(ext, ".svg")))
+ {
+ log_printf(_("Desktop file '%s' should not include
extension in Icon key: '%s'\n"),
+ editor->file, editor->icon);
+
+ // drop extension
+ *ext = '\0';
+ }
+ }
editor->exec = g_key_file_get_string(key_file, DESKTOP_GROUP, "Exec",
NULL);
- /* we take only editors that accept parameters, FIXME: the test can be
improved */
- if (!strchr(editor->exec, '%')) editor->hidden = TRUE;
-
+ /* we take only editors that accept parameters */
+ if (!editor_accepts_parameters(editor)) editor->hidden = TRUE;
+
editor->menu_path = g_key_file_get_string(key_file, DESKTOP_GROUP,
"X-Geeqie-Menu-Path", NULL);
if (!editor->menu_path) editor->menu_path =
g_strdup("EditMenu/ExternalMenu");
@@ -628,18 +674,7 @@
}
g_assert(p);
- while (*p != '\0')
- {
- /* must escape \, ", `, and $ to avoid problems,
- * we assume system shell supports bash-like escaping
- */
- if (strchr("\\\"`$", *p) != NULL)
- {
- string = g_string_append_c(string, '\\');
- }
- string = g_string_append_c(string, *p);
- p++;
- }
+ string = g_string_append(string, p);
if (type == PATH_FILE_URL) g_string_prepend(string, "file://");
pathl = path_from_utf8(string->str);
@@ -654,12 +689,46 @@
return pathl;
}
+static GString *append_quoted(GString *str, const char *s, gboolean
single_quotes, gboolean double_quotes)
+{
+ const char *p;
+
+ if (!single_quotes)
+ {
+ if (!double_quotes)
+ g_string_append_c(str, '\'');
+ else
+ g_string_append(str, "\"'");
+ }
+ for (p = s; *p != '\0'; p++)
+ {
+ if (*p == '\'')
+ g_string_append(str, "'\\''");
+ else
+ g_string_append_c(str, *p);
+ }
+
+ if (!single_quotes)
+ {
+ if (!double_quotes)
+ g_string_append_c(str, '\'');
+ else
+ g_string_append(str, "'\"");
+ }
+
+ return str;
+}
+
+
EditorFlags editor_command_parse(const EditorDescription *editor, GList *list,
gchar **output)
{
EditorFlags flags = 0;
const gchar *p;
GString *result = NULL;
+ gboolean escape = FALSE;
+ gboolean single_quotes = FALSE;
+ gboolean double_quotes = FALSE;
if (output)
result = g_string_new("");
@@ -678,12 +747,34 @@
while (*p)
{
- if (*p != '%')
+ if (escape)
{
+ escape = FALSE;
if (output) result = g_string_append_c(result, *p);
}
- else /* *p == '%' */
+ else if (*p == '\\')
{
+ if (!single_quotes) escape = TRUE;
+ if (output) result = g_string_append_c(result, *p);
+ }
+ else if (*p == '\'')
+ {
+ if (output) result = g_string_append_c(result, *p);
+ if (!single_quotes && !double_quotes)
+ single_quotes = TRUE;
+ else if (single_quotes)
+ single_quotes = FALSE;
+ }
+ else if (*p == '"')
+ {
+ if (output) result = g_string_append_c(result, *p);
+ if (!single_quotes && !double_quotes)
+ double_quotes = TRUE;
+ else if (double_quotes)
+ double_quotes = FALSE;
+ }
+ else if (*p == '%' && p[1])
+ {
gchar *pathl = NULL;
p++;
@@ -716,9 +807,7 @@
}
if (output)
{
- result =
g_string_append_c(result, '"');
- result =
g_string_append(result, pathl);
- result =
g_string_append_c(result, '"');
+ result =
append_quoted(result, pathl, single_quotes, double_quotes);
}
g_free(pathl);
}
@@ -751,9 +840,7 @@
{
ok =
TRUE;
if
(work != list) g_string_append_c(result, ' ');
- result
= g_string_append_c(result, '"');
- result
= g_string_append(result, pathl);
- result
= g_string_append_c(result, '"');
+ result
= append_quoted(result, pathl, single_quotes, double_quotes);
}
g_free(pathl);
}
@@ -767,21 +854,25 @@
}
break;
case 'i':
- if (output)
+ if (editor->icon && *editor->icon)
{
- result =
g_string_append(result, editor->icon);
+ if (output)
+ {
+ result =
g_string_append(result, "--icon ");
+ result =
append_quoted(result, editor->icon, single_quotes, double_quotes);
+ }
}
break;
case 'c':
if (output)
{
- result =
g_string_append(result, editor->name);
+ result = append_quoted(result,
editor->name, single_quotes, double_quotes);
}
break;
case 'k':
if (output)
{
- result =
g_string_append(result, editor->file);
+ result = append_quoted(result,
editor->file, single_quotes, double_quotes);
}
break;
case '%':
@@ -801,10 +892,19 @@
goto err;
}
}
+ else
+ {
+ if (output) result = g_string_append_c(result, *p);
+ }
p++;
}
- if (output) *output = g_string_free(result, FALSE);
+ if (output)
+ {
+ *output = g_string_free(result, FALSE);
+ DEBUG_3("Editor cmd: %s", *output);
+ }
+
return flags;
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
_______________________________________________
Geeqie-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geeqie-svn