[epiphany/mcatanzaro/#588] prefs-dialog: Fix crash when locale is saved by older Epiphany



commit 7349f5c1dcc3b5bae8589f1d57669ce800d42574
Author: Michael Catanzaro <mcatanzaro igalia com>
Date:   Tue Nov 27 11:55:43 2018 -0600

    prefs-dialog: Fix crash when locale is saved by older Epiphany
    
    I recently got bored and changed Epiphany from handling lowercase
    locales (e.g. es-es) to uppercase the country code (e.g. es-ES), since
    that's how all other browsers work and it's a bit weird for us to be
    different. I pushed similar changes to WebKit.
    
    But I made a mistake: upgrades from older versions of Epiphany were not
    handled properly. Values stored in GSettings that used to be valid now
    cause Epiphany to crash. This commit (a) converts the older values to
    ensure they are still considered valid, and (b) ensures that we don't
    crash even if the preference contains gibberish.
    
    Fixes #588

 src/prefs-dialog.c | 46 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 37 insertions(+), 9 deletions(-)
---
diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c
index 5d919710d..62e463a27 100644
--- a/src/prefs-dialog.c
+++ b/src/prefs-dialog.c
@@ -1469,6 +1469,38 @@ language_editor_selection_changed_cb (GtkTreeSelection *selection,
   language_editor_update_buttons (dialog);
 }
 
+static char *
+normalize_locale (const char *locale)
+{
+  char *result = g_strdup (locale);
+
+  /* The result we store in prefs looks like es-ES or en-US. We don't
+   * store codeset (not used in Accept-Langs) and we store with hyphen
+   * instead of underscore (ditto). So here we just uppercase the
+   * country code, converting e.g. es-es to es-ES. We have to do this
+   * because older versions of Epiphany stored locales as entirely
+   * lowercase.
+   */
+  for (char *p = strchr (result, '-'); p != NULL && *p != '\0'; p++)
+    *p = g_ascii_toupper (*p);
+
+  return result;
+}
+
+static char *
+language_for_locale (const char *locale)
+{
+  g_autoptr(GString) string = g_string_new (locale);
+
+  /* Before calling gnome_get_language_from_locale() we have to convert
+   * from web locales (e.g. es-ES) to UNIX (e.g. es_ES.UTF-8).
+   */
+  g_strdelimit (string->str, "-", '_');
+  g_string_append (string, ".UTF-8");
+
+  return gnome_get_language_from_locale (string->str, string->str);
+}
+
 static void
 create_language_section (PrefsDialog *dialog)
 {
@@ -1526,18 +1558,14 @@ create_language_section (PrefsDialog *dialog)
   /* Fill languages editor */
   for (i = 0; list[i]; i++) {
     const char *code = list[i];
-
     if (strcmp (code, "system") == 0) {
       add_system_language_entry (store);
     } else if (code[0] != '\0') {
-      char *text;
-
-      /* Change hyphens to underscores. */
-      g_strdelimit ((char *)code, "-", '_');
-      text = gnome_get_language_from_locale (code, code);
-      language_editor_add (dialog, code, text);
-
-      g_free (text);
+      g_autofree char *normalized_locale = normalize_locale (code);
+      if (normalized_locale != NULL) {
+        g_autofree char *language_name = language_for_locale (normalized_locale);
+        language_editor_add (dialog, normalized_locale, language_name);
+      }
     }
   }
   g_object_unref (store);


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