Fix up problems with escaping already-escaped text and not unescaping it. Ensure that icon names (icon attribute values) are properly escaped on saving. Don't escape text which is already escaped. Unescape names & commands for editing & re-escape them afterwards. (The GLib docs list only five character escapes, so this is easy...) Signed-off-by: Darren Salt Index: menueditor/menueditor-main-window.c =================================================================== --- menueditor/menueditor-main-window.c (revision 22595) +++ menueditor/menueditor-main-window.c (working copy) @@ -1520,12 +1520,12 @@ i = _find_attribute (attribute_names, "name"); if (i == -1) return; - name = g_strdup_printf (NAME_FORMAT, attribute_values[i]); + name = g_markup_printf_escaped (NAME_FORMAT, attribute_values[i]); j = _find_attribute (attribute_names, "cmd"); if (j == -1) return; - command = g_strdup_printf (COMMAND_FORMAT, attribute_values[j]); + command = g_markup_printf_escaped (COMMAND_FORMAT, attribute_values[j]); k = _find_attribute (attribute_names, "term"); l = _find_attribute (attribute_names, "snotify"); @@ -1559,7 +1559,7 @@ i = _find_attribute (attribute_names, "name"); if (i == -1) return; - name = g_strdup_printf (MENU_FORMAT, attribute_values[i]); + name = g_markup_printf_escaped (MENU_FORMAT, attribute_values[i]); j = _find_attribute (attribute_names, "icon"); if (j != -1 && *attribute_values[j]) @@ -1579,7 +1579,7 @@ g_queue_push_tail (state->parents, parent); } else if (!strcmp (element_name, "separator")) { - name = g_strdup_printf (SEPARATOR_FORMAT, _("--- separator ---")); + name = g_markup_printf_escaped (SEPARATOR_FORMAT, _("--- separator ---")); gtk_tree_store_append (treestore, &iter, iter_parent); gtk_tree_store_set (treestore, &iter, @@ -1589,12 +1589,12 @@ i = _find_attribute (attribute_names, "name"); if (i == -1) return; - name = g_strdup_printf (NAME_FORMAT, attribute_values[i]); + name = g_markup_printf_escaped (NAME_FORMAT, attribute_values[i]); j = _find_attribute (attribute_names, "cmd"); if (j == -1) return; - command = g_strdup_printf (COMMAND_FORMAT, attribute_values[j]); + command = g_markup_printf_escaped (COMMAND_FORMAT, attribute_values[j]); k = _find_attribute (attribute_names, "icon"); if (k != -1 && *attribute_values[k]) @@ -1615,7 +1615,7 @@ i = _find_attribute (attribute_names, "name"); if (i == -1) return; - name = g_strdup_printf (TITLE_FORMAT, attribute_values[i]); + name = g_markup_printf_escaped (TITLE_FORMAT, attribute_values[i]); j = _find_attribute (attribute_names, "icon"); if (j != -1 && *attribute_values[j]) @@ -1633,12 +1633,12 @@ i = _find_attribute (attribute_names, "type"); if (i == -1) return; - name = g_strdup_printf (INCLUDE_FORMAT, _("--- include ---")); + name = g_markup_printf_escaped (INCLUDE_FORMAT, _("--- include ---")); if (!strcmp (attribute_values[i], "file")) { j = _find_attribute (attribute_names, "src"); if (j != -1) { - command = g_strdup_printf (INCLUDE_PATH_FORMAT, attribute_values[j]); + command = g_markup_printf_escaped (INCLUDE_PATH_FORMAT, attribute_values[j]); gtk_tree_store_append (treestore, &iter, iter_parent); gtk_tree_store_set (treestore, &iter, @@ -1650,7 +1650,7 @@ else if (!strcmp (attribute_values[i], "system")) { gboolean do_legacy = TRUE, only_unique = TRUE; - command = g_strdup_printf (INCLUDE_FORMAT, _("system")); + command = g_markup_printf_escaped (INCLUDE_FORMAT, _("system")); j = _find_attribute (attribute_names, "style"); k = _find_attribute (attribute_names, "unique"); @@ -1841,10 +1841,11 @@ temp_set = set; while (*temp_set) { if (strlen (*temp_set) > 0 && !g_strrstr (*temp_set, "span")) { - text = g_markup_escape_text (*temp_set, strlen (*temp_set) * sizeof (gchar)); + text = *temp_set; /* already escaped */ } temp_set++; } + text = strdup (text ? text : ""); g_strfreev (set); return text; @@ -1894,17 +1895,24 @@ fprintf (state->file_menu, "%sfile_menu, " visible=\"no\""); - if (option_1 && strlen (option_1) > 0) - fprintf (state->file_menu, " icon=\"%s\"", option_1); - + if (option_1 && *option_1) + { + temp = g_markup_escape_text (option_1, -1); + fprintf (state->file_menu, " icon=\"%s\"", temp); + free (temp); + } fprintf (state->file_menu, "/>\n"); break; case MENU: fprintf (state->file_menu, "%s<menu name=\"%s\"", space, name); if (hidden) fprintf (state->file_menu, " visible=\"no\""); - if (option_1 && strlen (option_1) > 0) - fprintf (state->file_menu, " icon=\"%s\"", option_1); + if (option_1 && *option_1) + { + temp = g_markup_escape_text (option_1, -1); + fprintf (state->file_menu, " icon=\"%s\"", temp); + free (temp); + } if (gtk_tree_model_iter_has_child (model, iter)) fprintf (state->file_menu, ">\n"); else @@ -1914,8 +1922,12 @@ fprintf (state->file_menu, "%s<app name=\"%s\" cmd=\"%s\"", space, name, command); if (hidden) fprintf (state->file_menu, " visible=\"no\""); - if (option_1 && strlen (option_1) > 0) - fprintf (state->file_menu, " icon=\"%s\"", option_1); + if (option_1 && *option_1) + { + temp = g_markup_escape_text (option_1, -1); + fprintf (state->file_menu, " icon=\"%s\"", temp); + free (temp); + } if (option_2 && (strcmp (option_2, "true") == 0)) fprintf (state->file_menu, " term=\"%s\"", option_2); if (option_3 && (strcmp (option_3, "true") == 0)) @@ -1926,9 +1938,12 @@ fprintf (state->file_menu, "%s<builtin name=\"%s\" cmd=\"%s\"", space, name, command); if (hidden) fprintf (state->file_menu, " visible=\"no\""); - if (strlen (option_1) > 0) - fprintf (state->file_menu, " icon=\"%s\"", option_1); - + if (option_1 && *option_1) + { + temp = g_markup_escape_text (option_1, -1); + fprintf (state->file_menu, " icon=\"%s\"", temp); + free (temp); + } fprintf (state->file_menu, "/>\n"); break; case INCLUDE_FILE: @@ -1939,8 +1954,12 @@ break; case INCLUDE_SYSTEM: fprintf (state->file_menu, "%s<include type=\"system\"", space); - if (option_1 && strlen (option_1) > 0) - fprintf (state->file_menu, " style=\"%s\"", option_1); + if (option_1 && *option_1) + { + temp = g_markup_escape_text (option_1, -1); + fprintf (state->file_menu, " style=\"%s\"", temp); + free (temp); + } if (option_2 && (strcmp (option_2, "true") == 0)) fprintf (state->file_menu, " unique=\"%s\"", option_2); if (option_3 && (strcmp (option_3, "true") == 0)) Index: menueditor/menueditor-edit-dialog.c =================================================================== --- menueditor/menueditor-edit-dialog.c (revision 22595) +++ menueditor/menueditor-edit-dialog.c (working copy) @@ -374,6 +374,50 @@ } } +static gchar * +unescape_text (const gchar *markup) +{ + gchar *text, *ptr, c; + + if (markup == NULL) + return NULL; + + ptr = text = g_malloc (strlen (markup) + 1); + + while ((c = *markup++)) + { + if (G_UNLIKELY (c == '&')) + { + if (!memcmp (markup, "amp;", 4)) { + *ptr++ = '&'; + markup += 4; + } + else if (!memcmp (markup, "lt;", 3)) { + *ptr++ = '<'; + markup += 3; + } + else if (!memcmp (markup, "gt;", 3)) { + *ptr++ = '>'; + markup += 3; + } + else if (!memcmp (markup, "quot;", 5)) { + *ptr++ = '"'; + markup += 5; + } + else if (!memcmp (markup, "apos;", 5)) { + *ptr++ = '\''; + markup += 5; + } + } + else + *ptr++ = c; + } + *ptr = 0; + + return text; +} + + /******************/ /* public methods */ /******************/ @@ -410,8 +454,11 @@ { MenuEditorEditDialogPrivate *priv = MENUEDITOR_EDIT_DIALOG_GET_PRIVATE (dialog); - if (name) - gtk_entry_set_text (GTK_ENTRY (priv->entry_name), name); + if (name) { + char *temp = unescape_text (name); + gtk_entry_set_text (GTK_ENTRY (priv->entry_name), temp); + g_free (temp); + } } void @@ -419,8 +466,11 @@ { MenuEditorEditDialogPrivate *priv = MENUEDITOR_EDIT_DIALOG_GET_PRIVATE (dialog); - if (command) - gtk_entry_set_text (GTK_ENTRY (priv->entry_command), command); + if (command) { + char *temp = unescape_text (command); + gtk_entry_set_text (GTK_ENTRY (priv->entry_command), temp); + g_free (temp); + } } void @@ -431,8 +481,11 @@ if (icon && strlen (icon) > 0) { if (icon[0] != '/') { /* themed icon */ + char *temp; gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->radio_button_themed_icon), TRUE); - gtk_entry_set_text (GTK_ENTRY (priv->entry_themed_icon), icon); + temp = unescape_text (icon); + gtk_entry_set_text (GTK_ENTRY (priv->entry_themed_icon), temp); + g_free (temp); } else { /* path to icon */ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->radio_button_icon), TRUE);