diff --git a/ChangeLog b/ChangeLog index 1be8726fa5..db38112539 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2003-10-16 Michael Natterer + + * libgimpbase/gimputils.[ch]: new function which takes any string + and returns UTF-8 (it returns "(invalid UTF-8 string)" if all + conversion attempts fail). + + * app/core/gimpbrush.c + * app/core/gimpgradient.c + * app/core/gimppalette.c + * app/core/gimppattern.c + * app/xcf/xcf-read.c: use it. Fixes bug #79897. + 2003-10-16 Michael Natterer * app/widgets/gimppaletteeditor.c: added "realize" and diff --git a/app/core/gimpbrush-load.c b/app/core/gimpbrush-load.c index bb234d3d4f..4bcfa4d597 100644 --- a/app/core/gimpbrush-load.c +++ b/app/core/gimpbrush-load.c @@ -42,6 +42,8 @@ #include +#include "libgimpbase/gimpbase.h" + #include "core-types.h" #include "base/brush-scale.h" @@ -585,7 +587,10 @@ gimp_brush_load_brush (gint fd, /* Read in the brush name */ if ((bn_size = (header.header_size - sizeof (header)))) { + gchar *utf8; + name = g_new (gchar, bn_size); + if ((read (fd, name, bn_size)) < bn_size) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, @@ -596,13 +601,11 @@ gimp_brush_load_brush (gint fd, return NULL; } - if (!g_utf8_validate (name, -1, NULL)) - { - g_message (_("Invalid UTF-8 string in brush file '%s'."), - filename); - g_free (name); - name = NULL; - } + utf8 = gimp_any_to_utf8 (name, -1, + _("Invalid UTF-8 string in brush file '%s'."), + filename); + g_free (name); + name = utf8; } if (!name) diff --git a/app/core/gimpbrush.c b/app/core/gimpbrush.c index bb234d3d4f..4bcfa4d597 100644 --- a/app/core/gimpbrush.c +++ b/app/core/gimpbrush.c @@ -42,6 +42,8 @@ #include +#include "libgimpbase/gimpbase.h" + #include "core-types.h" #include "base/brush-scale.h" @@ -585,7 +587,10 @@ gimp_brush_load_brush (gint fd, /* Read in the brush name */ if ((bn_size = (header.header_size - sizeof (header)))) { + gchar *utf8; + name = g_new (gchar, bn_size); + if ((read (fd, name, bn_size)) < bn_size) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, @@ -596,13 +601,11 @@ gimp_brush_load_brush (gint fd, return NULL; } - if (!g_utf8_validate (name, -1, NULL)) - { - g_message (_("Invalid UTF-8 string in brush file '%s'."), - filename); - g_free (name); - name = NULL; - } + utf8 = gimp_any_to_utf8 (name, -1, + _("Invalid UTF-8 string in brush file '%s'."), + filename); + g_free (name); + name = utf8; } if (!name) diff --git a/app/core/gimpgradient.c b/app/core/gimpgradient.c index 57fde59703..13c0055a0a 100644 --- a/app/core/gimpgradient.c +++ b/app/core/gimpgradient.c @@ -374,28 +374,30 @@ gimp_gradient_load (const gchar *filename, fgets (line, 1024, file); if (! strncmp (line, "Name: ", strlen ("Name: "))) { - if (g_utf8_validate (line, -1, NULL)) - { - gimp_object_set_name (GIMP_OBJECT (gradient), - g_strstrip (&line[strlen ("Name: ")])); - } - else - { - g_message (_("Invalid UTF-8 string in gradient file '%s'."), - filename); - gimp_object_set_name (GIMP_OBJECT (gradient), _("Unnamed")); - } + gchar *utf8; + + utf8 = gimp_any_to_utf8 (&line[strlen ("Name: ")], -1, + _("Invalid UTF-8 string in gradient file '%s'."), + filename); + g_strstrip (utf8); + + gimp_object_set_name (GIMP_OBJECT (gradient), utf8); + g_free (utf8); fgets (line, 1024, file); } else /* old gradient format */ { gchar *basename; + gchar *utf8; basename = g_path_get_basename (filename); - gimp_object_set_name (GIMP_OBJECT (gradient), basename); + utf8 = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL); g_free (basename); + + gimp_object_set_name (GIMP_OBJECT (gradient), utf8); + g_free (utf8); } num_segments = atoi (line); diff --git a/app/core/gimppalette-load.c b/app/core/gimppalette-load.c index e9f11fc81c..0f8bc6657f 100644 --- a/app/core/gimppalette-load.c +++ b/app/core/gimppalette-load.c @@ -28,6 +28,7 @@ #include +#include "libgimpbase/gimpbase.h" #include "libgimpcolor/gimpcolor.h" #include "core-types.h" @@ -430,16 +431,14 @@ gimp_palette_load (const gchar *filename, if (! strncmp (str, "Name: ", strlen ("Name: "))) { - if (g_utf8_validate (str, -1, NULL)) - { - gimp_object_set_name (GIMP_OBJECT (palette), - g_strstrip (&str[strlen ("Name: ")])); - } - else - { - g_message (_("Invalid UTF-8 string in palette file '%s'"), filename); - gimp_object_set_name (GIMP_OBJECT (palette), _("Unnamed")); - } + gchar *utf8; + + utf8 = gimp_any_to_utf8 (&str[strlen ("Name: ")], -1, + _("Invalid UTF-8 string in palette file '%s'"), + filename); + g_strstrip (utf8); + + gimp_object_set_name (GIMP_OBJECT (palette), utf8); if (! fgets (str, 1024, fp)) { @@ -485,11 +484,15 @@ gimp_palette_load (const gchar *filename, else /* old palette format */ { gchar *basename; + gchar *utf8; basename = g_path_get_basename (filename); - gimp_object_set_name (GIMP_OBJECT (palette), basename); + utf8 = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL); g_free (basename); + + gimp_object_set_name (GIMP_OBJECT (palette), utf8); + g_free (utf8); } while (! feof (fp)) diff --git a/app/core/gimppalette-save.c b/app/core/gimppalette-save.c index e9f11fc81c..0f8bc6657f 100644 --- a/app/core/gimppalette-save.c +++ b/app/core/gimppalette-save.c @@ -28,6 +28,7 @@ #include +#include "libgimpbase/gimpbase.h" #include "libgimpcolor/gimpcolor.h" #include "core-types.h" @@ -430,16 +431,14 @@ gimp_palette_load (const gchar *filename, if (! strncmp (str, "Name: ", strlen ("Name: "))) { - if (g_utf8_validate (str, -1, NULL)) - { - gimp_object_set_name (GIMP_OBJECT (palette), - g_strstrip (&str[strlen ("Name: ")])); - } - else - { - g_message (_("Invalid UTF-8 string in palette file '%s'"), filename); - gimp_object_set_name (GIMP_OBJECT (palette), _("Unnamed")); - } + gchar *utf8; + + utf8 = gimp_any_to_utf8 (&str[strlen ("Name: ")], -1, + _("Invalid UTF-8 string in palette file '%s'"), + filename); + g_strstrip (utf8); + + gimp_object_set_name (GIMP_OBJECT (palette), utf8); if (! fgets (str, 1024, fp)) { @@ -485,11 +484,15 @@ gimp_palette_load (const gchar *filename, else /* old palette format */ { gchar *basename; + gchar *utf8; basename = g_path_get_basename (filename); - gimp_object_set_name (GIMP_OBJECT (palette), basename); + utf8 = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL); g_free (basename); + + gimp_object_set_name (GIMP_OBJECT (palette), utf8); + g_free (utf8); } while (! feof (fp)) diff --git a/app/core/gimppalette.c b/app/core/gimppalette.c index e9f11fc81c..0f8bc6657f 100644 --- a/app/core/gimppalette.c +++ b/app/core/gimppalette.c @@ -28,6 +28,7 @@ #include +#include "libgimpbase/gimpbase.h" #include "libgimpcolor/gimpcolor.h" #include "core-types.h" @@ -430,16 +431,14 @@ gimp_palette_load (const gchar *filename, if (! strncmp (str, "Name: ", strlen ("Name: "))) { - if (g_utf8_validate (str, -1, NULL)) - { - gimp_object_set_name (GIMP_OBJECT (palette), - g_strstrip (&str[strlen ("Name: ")])); - } - else - { - g_message (_("Invalid UTF-8 string in palette file '%s'"), filename); - gimp_object_set_name (GIMP_OBJECT (palette), _("Unnamed")); - } + gchar *utf8; + + utf8 = gimp_any_to_utf8 (&str[strlen ("Name: ")], -1, + _("Invalid UTF-8 string in palette file '%s'"), + filename); + g_strstrip (utf8); + + gimp_object_set_name (GIMP_OBJECT (palette), utf8); if (! fgets (str, 1024, fp)) { @@ -485,11 +484,15 @@ gimp_palette_load (const gchar *filename, else /* old palette format */ { gchar *basename; + gchar *utf8; basename = g_path_get_basename (filename); - gimp_object_set_name (GIMP_OBJECT (palette), basename); + utf8 = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL); g_free (basename); + + gimp_object_set_name (GIMP_OBJECT (palette), utf8); + g_free (utf8); } while (! feof (fp)) diff --git a/app/core/gimppattern-load.c b/app/core/gimppattern-load.c index b43effce69..d49066df55 100644 --- a/app/core/gimppattern-load.c +++ b/app/core/gimppattern-load.c @@ -41,6 +41,8 @@ #define _O_BINARY 0 #endif +#include "libgimpbase/gimpbase.h" + #include "core-types.h" #include "config/gimpbaseconfig.h" @@ -390,6 +392,8 @@ gimp_pattern_load (const gchar *filename, /* Read in the pattern name */ if ((bn_size = (header.header_size - sizeof (header)))) { + gchar *utf8; + name = g_new (gchar, bn_size); if ((read (fd, name, bn_size)) < bn_size) @@ -400,13 +404,11 @@ gimp_pattern_load (const gchar *filename, goto error; } - if (!g_utf8_validate (name, -1, NULL)) - { - g_message (_("Invalid UTF-8 string in pattern file '%s'."), - filename); - g_free (name); - name = NULL; - } + utf8 = gimp_any_to_utf8 (name, -1, + _("Invalid UTF-8 string in pattern file '%s'."), + filename); + g_free (name); + name = utf8; } if (!name) diff --git a/app/core/gimppattern.c b/app/core/gimppattern.c index b43effce69..d49066df55 100644 --- a/app/core/gimppattern.c +++ b/app/core/gimppattern.c @@ -41,6 +41,8 @@ #define _O_BINARY 0 #endif +#include "libgimpbase/gimpbase.h" + #include "core-types.h" #include "config/gimpbaseconfig.h" @@ -390,6 +392,8 @@ gimp_pattern_load (const gchar *filename, /* Read in the pattern name */ if ((bn_size = (header.header_size - sizeof (header)))) { + gchar *utf8; + name = g_new (gchar, bn_size); if ((read (fd, name, bn_size)) < bn_size) @@ -400,13 +404,11 @@ gimp_pattern_load (const gchar *filename, goto error; } - if (!g_utf8_validate (name, -1, NULL)) - { - g_message (_("Invalid UTF-8 string in pattern file '%s'."), - filename); - g_free (name); - name = NULL; - } + utf8 = gimp_any_to_utf8 (name, -1, + _("Invalid UTF-8 string in pattern file '%s'."), + filename); + g_free (name); + name = utf8; } if (!name) diff --git a/app/xcf/xcf-read.c b/app/xcf/xcf-read.c index f9f596b3b0..e78d1343d6 100644 --- a/app/xcf/xcf-read.c +++ b/app/xcf/xcf-read.c @@ -22,6 +22,8 @@ #include +#include "libgimpbase/gimpbase.h" + #include "xcf-read.h" #include "gimp-intl.h" @@ -101,21 +103,10 @@ xcf_read_string (FILE *fp, if (str[tmp - 1] != '\0') str[tmp - 1] = '\0'; - if (! g_utf8_validate (str, -1, NULL)) - { - gchar *utf8_str; + data[i] = gimp_any_to_utf8 (str, -1, + _("Invalid UTF-8 string in XCF file")); - utf8_str = g_locale_to_utf8 (str, -1, NULL, NULL, NULL); - - g_free (str); - - if (utf8_str) - str = utf8_str; - else - str = g_strdup (_("(invalid UTF-8 string)")); - } - - data[i] = str; + g_free (str); } else { diff --git a/libgimpbase/gimputils.c b/libgimpbase/gimputils.c index 0a26adbedd..8640267a6d 100644 --- a/libgimpbase/gimputils.c +++ b/libgimpbase/gimputils.c @@ -40,7 +40,7 @@ * Creates a (possibly trimmed) copy of @str. The string is cut if it * exceeds @max_chars characters or on the first newline. The fact * that the string was trimmed is indicated by appending an ellipsis. - * + * * Returns: A (possibly trimmed) copy of @str which should be freed * using g_free() when it is not needed any longer. **/ @@ -99,15 +99,86 @@ gimp_utf8_strtrim (const gchar *str, return NULL; } +/** + * gimp_any_to_utf8: + * @str: The string to be converted to UTF-8. + * @len: The length of the string, or -1 if the string + * is nul-terminated. + * @warning_format: The message format for the warning message if conversion + * to UTF-8 fails. See the printf() + * documentation. + * @Varargs: The parameters to insert into the format string. + * + * This function takes any string (UTF-8 or not) and always returns a valid + * UTF-8 string. + * + * If @str is valid UTF-8, a copy of the string is returned. + * + * If UTF-8 validation fails, g_locale_to_utf8() is tried and if it + * succeeds the resulting string is returned. + * + * Otherwise, the portion of @str that is UTF-8, concatenated + * with "(invalid UTF-8 string)" is returned. If not even the start + * of @str is valid UTF-8, only "(invalid UTF-8 string)" is returned. + * + * Return value: The UTF-8 string as described above. + **/ +gchar * +gimp_any_to_utf8 (const gchar *str, + gssize len, + const gchar *warning_format, + ...) +{ + const gchar *start_invalid; + gchar *utf8; + + g_return_val_if_fail (str != NULL, NULL); + + if (g_utf8_validate (str, len, &start_invalid)) + utf8 = g_strdup (str); + else + utf8 = g_locale_to_utf8 (str, len, NULL, NULL, NULL); + + if (! utf8) + { + if (warning_format) + { + va_list warning_args; + + va_start (warning_args, warning_format); + + g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, + warning_format, warning_args); + + va_end (warning_args); + } + + if (start_invalid > str) + { + gchar *tmp; + + tmp = g_strndup (str, start_invalid - str); + utf8 = g_strconcat (tmp, _("(invalid UTF-8 string)"), NULL); + g_free (tmp); + } + else + { + utf8 = g_strdup (_("(invalid UTF-8 string)")); + } + } + + return utf8; +} + /** * gimp_memsize_to_string: * @memsize: A memory size in bytes. - * + * * This function returns a human readable, translated representation * of the passed @memsize. Large values are rounded to the closest * reasonable memsize unit, e.g.: "3456" becomes "3456 Bytes", "4100" * becomes "4 KB" and so on. - * + * * Return value: A human-readable, translated string. **/ gchar * diff --git a/libgimpbase/gimputils.h b/libgimpbase/gimputils.h index cc87477c15..7401773cf3 100644 --- a/libgimpbase/gimputils.h +++ b/libgimpbase/gimputils.h @@ -1,14 +1,14 @@ -/* LIBGIMP - The GIMP Library +/* LIBGIMP - The GIMP Library * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public @@ -23,6 +23,10 @@ gchar * gimp_utf8_strtrim (const gchar *str, gint max_chars); +gchar * gimp_any_to_utf8 (const gchar *str, + gssize len, + const gchar *warning_format, + ...) G_GNUC_PRINTF (3, 4); gchar * gimp_memsize_to_string (gulong memsize);