[PATCH] Fix broken handling of non-ASCII strings
Mark H Weaver <[email protected]> Wed, 20 Apr 2011 13:59:03 -0400
| Newsgroups | gmane.lisp.guile.gtk |
|---|---|
| Message-ID | <[email protected]> |
Hello all, David Pirotte <[email protected]> reported on #guile that gtk-text-buffer-set-text dropped the last character of the provided string if it contained a latin-1 character. More generally, it fails if any non-ASCII characters are present. Upon investigation, I discovered that whereas the GTK interfaces generally expect a UTF-8 encoded string and a length in _bytes_, guile-gnome is instead passing a locale-encoded string and a length in _characters_. The attached patches fix this problem in only a few places related to GTK Text widgets. I'm reasonably sure that there are _many_ other similar bugs. The vast majority of uses of scm_from_locale_* and scm_to_locale_*, both in guile-gnome and in guile itself, are erroneous. If someone else would be willing to fix the rest of these bugs in guile-gnome, it would be most appreciated. I'd prefer to concentrate on guile core for now. Best, Mark _______________________________________________ guile-gtk-general mailing list [email protected] http://lists.gnu.org/mailman/listinfo/guile-gtk-general
STRING_ENCODING_FIX_GLIB.patch
(text/x-diff, 944 B)
diff --git a/gnome/gobject/guile-support.c b/gnome/gobject/guile-support.c
index c6bd947..51dbb97 100644
--- a/gnome/gobject/guile-support.c
+++ b/gnome/gobject/guile-support.c
@@ -34,6 +34,14 @@ scm_to_locale_string_dynwind (SCM s)
}
char*
+scm_to_utf8_stringn_dynwind (SCM s, size_t *lenp)
+{
+ char *ret = scm_to_utf8_stringn (s, lenp);
+ scm_dynwind_free (ret);
+ return ret;
+}
+
+char*
scm_symbol_chars (SCM s)
{
return scm_to_locale_string (scm_symbol_to_string (s));
diff --git a/gnome/gobject/guile-support.h b/gnome/gobject/guile-support.h
index 41f01af..4b10b7d 100644
--- a/gnome/gobject/guile-support.h
+++ b/gnome/gobject/guile-support.h
@@ -34,6 +34,7 @@ G_BEGIN_DECLS
#define SCM_VERSION_17X 1
char* scm_to_locale_string_dynwind (SCM s);
+char* scm_to_utf8_stringn_dynwind (SCM s, size_t *lenp);
char* scm_symbol_chars (SCM s);
char* scm_symbol_chars_dynwind (SCM s);
char* scm_keyword_chars (SCM s);
STRING_ENCODING_FIX_GTK.patch
(text/x-diff, 5.2 KB)
diff --git a/gnome/gw/gtk-support.c b/gnome/gw/gtk-support.c
index 1876c77..cc3815c 100644
--- a/gnome/gw/gtk-support.c
+++ b/gnome/gw/gtk-support.c
@@ -517,9 +517,13 @@ void
_wrap_gtk_text_buffer_set_text (GtkTextBuffer *buf, SCM stext)
#define FUNC_NAME "gtk-text-buffer-set-text"
{
+ char *utf8_text;
+ size_t utf8_len;
+
SCM_VALIDATE_STRING (2, stext);
scm_dynwind_begin (0);
- gtk_text_buffer_set_text (buf, scm_to_locale_string_dynwind (stext), scm_c_string_length (stext));
+ utf8_text = scm_to_utf8_stringn_dynwind (stext, &utf8_len);
+ gtk_text_buffer_set_text (buf, utf8_text, utf8_len);
scm_dynwind_end ();
}
#undef FUNC_NAME
@@ -528,9 +532,13 @@ void
_wrap_gtk_text_buffer_insert (GtkTextBuffer *buf, GtkTextIter* iter, SCM stext)
#define FUNC_NAME "gtk-text-buffer-insert"
{
+ char *utf8_text;
+ size_t utf8_len;
+
SCM_VALIDATE_STRING (3, stext);
scm_dynwind_begin (0);
- gtk_text_buffer_insert (buf, iter, scm_to_locale_string_dynwind (stext), scm_c_string_length (stext));
+ utf8_text = scm_to_utf8_stringn_dynwind (stext, &utf8_len);
+ gtk_text_buffer_insert (buf, iter, utf8_text, utf8_len);
scm_dynwind_end ();
}
#undef FUNC_NAME
@@ -539,9 +547,13 @@ void
_wrap_gtk_text_buffer_insert_at_cursor (GtkTextBuffer *buf, SCM stext)
#define FUNC_NAME "gtk-text-buffer-insert-at-cursor"
{
+ char *utf8_text;
+ size_t utf8_len;
+
SCM_VALIDATE_STRING (2, stext);
scm_dynwind_begin (0);
- gtk_text_buffer_insert_at_cursor (buf, scm_to_locale_string_dynwind (stext), scm_c_string_length (stext));
+ utf8_text = scm_to_utf8_stringn_dynwind (stext, &utf8_len);
+ gtk_text_buffer_insert_at_cursor (buf, utf8_text, utf8_len);
scm_dynwind_end ();
}
#undef FUNC_NAME
@@ -551,12 +563,15 @@ _wrap_gtk_text_buffer_insert_interactive (GtkTextBuffer *buf, GtkTextIter* iter,
SCM stext, gboolean default_editable)
#define FUNC_NAME "gtk-text-buffer-insert-interactive"
{
+ char *utf8_text;
+ size_t utf8_len;
gboolean ret;
SCM_VALIDATE_STRING (3, stext);
scm_dynwind_begin (0);
- ret = gtk_text_buffer_insert_interactive (buf, iter, scm_to_locale_string_dynwind (stext),
- scm_c_string_length (stext), default_editable);
+ utf8_text = scm_to_utf8_stringn_dynwind (stext, &utf8_len);
+ ret = gtk_text_buffer_insert_interactive (buf, iter, utf8_text, utf8_len,
+ default_editable);
scm_dynwind_end ();
return ret;
}
@@ -567,11 +582,14 @@ _wrap_gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buf, SCM stex
gboolean default_editable)
#define FUNC_NAME "gtk-text-buffer-insert-interactive-at-cursor"
{
+ char *utf8_text;
+ size_t utf8_len;
gboolean ret;
+
SCM_VALIDATE_STRING (2, stext);
scm_dynwind_begin (0);
- ret = gtk_text_buffer_insert_interactive_at_cursor (buf, scm_to_locale_string_dynwind (stext),
- scm_c_string_length (stext),
+ utf8_text = scm_to_utf8_stringn_dynwind (stext, &utf8_len);
+ ret = gtk_text_buffer_insert_interactive_at_cursor (buf, utf8_text, utf8_len,
default_editable);
scm_dynwind_end ();
return ret;
@@ -583,6 +601,8 @@ _wrap_gtk_text_buffer_insert_with_tags (GtkTextBuffer *buf, GtkTextIter* iter,
SCM stext, GList* tag_list)
#define FUNC_NAME "gtk-text-buffer-insert-with-tags"
{
+ char *utf8_text;
+ size_t utf8_len;
GtkTextIter start;
GList *walk;
gint start_offset;
@@ -592,8 +612,8 @@ _wrap_gtk_text_buffer_insert_with_tags (GtkTextBuffer *buf, GtkTextIter* iter,
SCM_VALIDATE_STRING (3, stext);
scm_dynwind_begin (0);
start_offset = gtk_text_iter_get_offset (iter);
- gtk_text_buffer_insert (buf, iter, scm_to_locale_string_dynwind (stext),
- scm_c_string_length (stext));
+ utf8_text = scm_to_utf8_stringn_dynwind (stext, &utf8_len);
+ gtk_text_buffer_insert (buf, iter, utf8_text, utf8_len);
gtk_text_buffer_get_iter_at_offset (buf, &start, start_offset);
for (walk = tag_list; walk; walk = walk->next)
@@ -608,6 +628,8 @@ _wrap_gtk_text_buffer_insert_with_tags_by_name (GtkTextBuffer *buf, GtkTextIter*
SCM stext, GList* tag_list)
#define FUNC_NAME "gtk-text-buffer-insert-with-tags-by-name"
{
+ char *utf8_text;
+ size_t utf8_len;
GtkTextIter start;
GList *walk;
gint start_offset;
@@ -617,8 +639,8 @@ _wrap_gtk_text_buffer_insert_with_tags_by_name (GtkTextBuffer *buf, GtkTextIter*
SCM_VALIDATE_STRING (3, stext);
scm_dynwind_begin (0);
start_offset = gtk_text_iter_get_offset (iter);
- gtk_text_buffer_insert (buf, iter, scm_to_locale_string_dynwind (stext),
- scm_c_string_length (stext));
+ utf8_text = scm_to_utf8_stringn_dynwind (stext, &utf8_len);
+ gtk_text_buffer_insert (buf, iter, utf8_text, utf8_len);
gtk_text_buffer_get_iter_at_offset (buf, &start, start_offset);
for (walk = tag_list; walk; walk = walk->next)