- fix for error with utf8 textinput for buttons
authorCampbell Barton <ideasman42@gmail.com>
Sun, 23 Oct 2011 13:52:51 +0000 (13:52 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 23 Oct 2011 13:52:51 +0000 (13:52 +0000)
- ensure input is valid utf8 from ghost and NULL then complain if its not.
- added function to get utf8 size BLI_str_utf8_size()

source/blender/blenlib/BLI_string_utf8.h
source/blender/blenlib/intern/string_utf8.c
source/blender/editors/interface/interface_handlers.c
source/blender/makesrna/intern/rna_wm.c
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_event_system.c

index 765ae93..bcb641d 100644 (file)
@@ -37,6 +37,7 @@ char        *BLI_strncpy_utf8(char *dst, const char *src, size_t maxncpy);
 int          BLI_utf8_invalid_byte(const char *str, int length);
 int          BLI_utf8_invalid_strip(char *str, int length);
 
+int          BLI_str_utf8_size(const char *p); /* warning, can return -1 on bad chars */
     /* copied from glib */
 unsigned int BLI_str_utf8_as_unicode(const char *p);
 unsigned int BLI_str_utf8_as_unicode_and_size(const char *p, size_t *index);
index b1ad04e..b4c58d3 100644 (file)
@@ -312,6 +312,18 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst_w, const char *src_c, const size
        }
 
 
+/* uses glib functions but not from glib */
+/* gets the size of a single utf8 char */
+int BLI_str_utf8_size(const char *p)
+{
+       int mask = 0, len;
+    unsigned char c = (unsigned char) *p;
+
+    UTF8_COMPUTE (c, mask, len);
+
+       return len;
+}
+
 /* was g_utf8_get_char */
 /**
  * BLI_str_utf8_as_unicode:
index 79080eb..9f77317 100644 (file)
@@ -1447,7 +1447,7 @@ static int ui_textedit_type_utf8(uiBut *but, uiHandleButtonData *data, const cha
        len= strlen(str);
 
        if(len-(but->selend - but->selsta)+1 <= data->maxlen) {
-               int step= BLI_strnlen(utf8_buf, sizeof(utf8_buf));
+               int step= BLI_str_utf8_size(utf8_buf);
 
                /* type over the current selection */
                if ((but->selend - but->selsta) > 0) {
index dc9f003..942c0d3 100644 (file)
@@ -492,9 +492,7 @@ static int rna_Event_unicode_length(PointerRNA *ptr)
 
        wmEvent *event= (wmEvent*)ptr->data;
        if (event->utf8_buf[0]) {
-               size_t len= 0;
-               BLI_str_utf8_as_unicode_and_size(event->utf8_buf, &len);
-               return (int)len;
+               return BLI_str_utf8_size(event->utf8_buf); /* invalid value is checked on assignment so we dont need to account for this */
        }
        else {
                return 0;
index 5048166..fc96c88 100644 (file)
@@ -346,7 +346,9 @@ typedef struct wmEvent {
        short val;                      /* press, release, scrollvalue */
        int x, y;                       /* mouse pointer position, screen coord */
        int mval[2];            /* region mouse position, name convention pre 2.5 :) */
-       char utf8_buf[6];       /* from, ghost if utf8 is enabled for the platform */
+       char utf8_buf[6];       /* from, ghost if utf8 is enabled for the platform,
+                                                * BLI_str_utf8_size() must _always_ be valid, check
+                                                * when assigning s we dont need to check on every access after */
        char ascii;                     /* from ghost, fallback if utf8 isnt set */
        char pad;
 
index 3e9bce6..09ec8bf 100644 (file)
@@ -454,11 +454,12 @@ void WM_event_print(wmEvent *event)
 
                printf("wmEvent - type:%d/%s, val:%d/%s, "
                           "shift:%d, ctrl:%d, alt:%d, oskey:%d, keymodifier:%d, "
-                          "mouse:(%d,%d), ascii:'%c', utf8:'%.6s', "
+                          "mouse:(%d,%d), ascii:'%c', utf8:'%.*s', "
                           "keymap_idname:%s, pointer:%p\n",
                           event->type, type_id, event->val, val_id,
                           event->shift, event->ctrl, event->alt, event->oskey, event->keymodifier,
-                          event->x, event->y, event->ascii, event->utf8_buf,
+                          event->x, event->y, event->ascii,
+                      BLI_str_utf8_size(event->utf8_buf), event->utf8_buf,
                           event->keymap_idname, (void *)event);
        }
        else {
@@ -2629,6 +2630,13 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
                                /* TODO. should this also zero utf8?, dont for now, campbell */
                        }
 
+                       if (event.utf8_buf[0]) {
+                               if (BLI_str_utf8_size(event.utf8_buf) == -1) {
+                                       printf("%s: ghost detected an invalid unicode character '%d'!\n", __func__, (int)(unsigned char)event.utf8_buf[0]);
+                                       event.utf8_buf[0]= '\0';
+                               }
+                       }
+
                        /* modifiers */
                        /* assigning both first and second is strange - campbell */
                        switch(event.type) {