guile-gtk-general
[Top][All Lists]
Advanced

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

[PATCH] Fix broken handling of non-ASCII strings


From: Mark H Weaver
Subject: [PATCH] Fix broken handling of non-ASCII strings
Date: Wed, 20 Apr 2011 13:59:03 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux)

Hello all,

David Pirotte <address@hidden> 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


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);
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)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]