discomfitor pushed a commit to branch enlightenment-0.22.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=781f4eb70bd76582b334554457221302a8e3d3b0

commit 781f4eb70bd76582b334554457221302a8e3d3b0
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Tue Mar 27 18:57:44 2018 +0900

    e menus - when filtering for exe handle quotes, escapes etc.
    
    handle quotes, escapes and so on for the shell command so you can do
    things like Exec="ls" and it still work. this will also allow
    executables with spaces in them as well with quotes or escapes as
    backslash.
    
    this fixes T6787
    @fix
---
 src/bin/e_int_menus.c | 102 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 88 insertions(+), 14 deletions(-)

diff --git a/src/bin/e_int_menus.c b/src/bin/e_int_menus.c
index 10110f900..8d18e2983 100644
--- a/src/bin/e_int_menus.c
+++ b/src/bin/e_int_menus.c
@@ -694,6 +694,80 @@ _e_int_menus_main_exit(void *data EINA_UNUSED, E_Menu *m 
EINA_UNUSED, E_Menu_Ite
    if ((a) && (a->func.go)) a->func.go(NULL, NULL);
 }
 
+static char *
+_e_int_menus_app_exe_get(const char *exec)
+{
+   char *real, *d;
+   const char *s;
+   Eina_Bool in_quote_dbl = EINA_FALSE;
+   Eina_Bool in_quote = EINA_FALSE;
+
+   real = malloc(strlen(exec) + 1);
+   if (!real) return NULL;
+   for (d = real, s = exec; *s; s++)
+     {
+        if (in_quote_dbl)
+          {
+             switch (*s)
+               {
+                case '\"':
+                  in_quote_dbl = EINA_FALSE;
+                  break;
+                case '\\':
+                  s++;
+                  EINA_FALLTHROUGH
+                default:
+                  *d = *s;
+                  d++;
+                  break;
+               }
+          }
+        else if (in_quote)
+          {
+             switch (*s)
+               {
+                case '\'':
+                  in_quote = EINA_FALSE;
+                  break;
+                case '\\':
+                  s++;
+                  EINA_FALLTHROUGH
+                default:
+                  *d = *s;
+                  d++;
+                  break;
+               }
+          }
+        else
+          {
+             switch (*s)
+               {
+                case ' ':
+                case '\t':
+                case '\r':
+                case '\n':
+                  goto done;
+                  break;
+                case '\"':
+                  in_quote_dbl = EINA_TRUE;
+                  break;
+                case '\'':
+                  in_quote = EINA_TRUE;
+                  break;
+                case '\\':
+                  s++;
+                  EINA_FALLTHROUGH
+                default:
+                  *d = *s;
+                  d++;
+                  break;
+               }
+          }
+     }
+done:
+   *d = 0;
+   return real;
+}
 /*
  * This function searches $PATH for try_exec or exec
  * return true if try_exec or exec is found!
@@ -705,23 +779,31 @@ _e_int_menus_app_finder(const char *exec)
    char **split, buf[PATH_MAX];
    Eina_Bool exec_found = EINA_FALSE;
    int i = 0;
+   char *real = NULL;
 
-   if (strchr(exec, '/'))
+   if (!exec) return EINA_FALSE;
+   real = _e_int_menus_app_exe_get(exec);
+   if (!real) return EINA_FALSE;
+   if (strchr(real, '/'))
      {
-        if (ecore_file_exists(exec) && ecore_file_can_exec(exec))
-          return EINA_TRUE;
+        if (ecore_file_exists(real) && ecore_file_can_exec(real))
+          {
+             free(real);
+             return EINA_TRUE;
+          }
      }
 
    if (!env)
      {
         WRN("Unable to $PATH, Returning TRUE for every .desktop");
+        free(real);
         return EINA_TRUE;
      }
 
    split = eina_str_split(env, ":", 0);
    for (i = 0; split[i] != NULL; i++)
      {
-        snprintf(buf, sizeof(buf), "%s/%s", split[i], exec);
+        snprintf(buf, sizeof(buf), "%s/%s", split[i], real);
 
         if (ecore_file_exists(buf) && ecore_file_can_exec(buf))
           {
@@ -735,6 +817,7 @@ _e_int_menus_app_finder(const char *exec)
    if (!exec_found)
      WRN("Unable to find: [%s] I searched $PATH=%s", exec, env);
 
+   free(real);
    return exec_found;
 }
 
@@ -795,16 +878,7 @@ _e_int_menus_app_config_append(Efreet_Desktop *desktop)
      }
    else if (cma->exec)
      {
-        if (!strchr(cma->exec, ' '))
-          cma->exec_valid = _e_int_menus_app_finder(cma->exec);
-        else
-          {
-             char **split;
-             split = eina_str_split(cma->exec, " ", 0);
-             cma->exec_valid = _e_int_menus_app_finder(split[0]);
-             free(split[0]);
-             free(split);
-          }
+        cma->exec_valid = _e_int_menus_app_finder(cma->exec);
      }
 
    e_config->menu_applications = eina_list_append(e_config->menu_applications, 
cma);

-- 


Reply via email to