[gnome-panel/wip/muktupavels/issue-17] panel-run-dialog: fix endless loop in remove_parameters



commit db9e1f4e77e087c96b554d869e3b125942831d3f
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Fri Aug 2 23:41:28 2019 +0300

    panel-run-dialog: fix endless loop in remove_parameters
    
    https://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables
    
    According to specification double %% are used to escape literal
    percentage character. In this case first percentage is removed and
    then strstr returns pointer to literal percentage. If this percentage
    + next alpha character does not make recognized field code we enter
    endless loop.
    
    Rewrite function to properly handle literal percentage character and
    at the same time rename function to remove_field_codes as it seems
    more appropriate name for what it is doing.
    
    https://gitlab.gnome.org/GNOME/gnome-panel/issues/17

 gnome-panel/panel-run-dialog.c | 42 +++++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 17 deletions(-)
---
diff --git a/gnome-panel/panel-run-dialog.c b/gnome-panel/panel-run-dialog.c
index 856b27500..69ef55df1 100644
--- a/gnome-panel/panel-run-dialog.c
+++ b/gnome-panel/panel-run-dialog.c
@@ -1021,41 +1021,49 @@ panel_run_dialog_add_items_idle (PanelRunDialog *dialog)
 }
 
 static char *
-remove_parameters (const char *exec)
+remove_field_codes (const char *exec)
 {
-       GString *str;
-       char    *retval, *p;
+       char *retval;
+       char *p;
 
-       str = g_string_new (exec);
+       if (exec == NULL || *exec == '\0')
+               return g_strdup ("");
 
-       while ((p = strstr (str->str, "%"))) {
-               switch (p [1]) {
+       retval = g_new0 (char, strlen (exec) + 1);
+       p = retval;
+
+       while (*exec != '\0') {
+               if (*exec != '%') {
+                       *p++ = *exec++;
+                       continue;
+               }
+
+               switch (exec[1]) {
                case '%':
-                       g_string_erase (str, p - str->str, 1);
+                       *p++ = *exec++;
+                       exec++;
                        break;
-               case 'U':
-               case 'F':
-               case 'N':
-               case 'D':
                case 'f':
+               case 'F':
                case 'u':
+               case 'U':
                case 'd':
+               case 'D':
                case 'n':
-               case 'm':
+               case 'N':
                case 'i':
                case 'c':
                case 'k':
                case 'v':
-                       g_string_erase (str, p - str->str, 2);
+               case 'm':
+                       exec += 2;
                        break;
                default:
+                       *p++ = *exec++;
                        break;
                }
        }
 
-       retval = str->str;
-       g_string_free (str, FALSE);
-
        return retval;
 }
 
@@ -1113,7 +1121,7 @@ program_list_selection_changed (GtkTreeSelection *selection,
        entry = gtk_bin_get_child (GTK_BIN (dialog->combobox));
        temp = panel_key_file_get_string (key_file, "Exec");
        if (temp) {
-               stripped = remove_parameters (temp);
+               stripped = remove_field_codes (temp);
                gtk_entry_set_text (GTK_ENTRY (entry), stripped);
                g_free (stripped);
        } else {


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