From cf08068e10040a3f4d5548bfcb4e4940d2f75d8d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 9 Nov 2012 03:36:38 +0000 Subject: fix [#33121] crashing when srolling down in text editor ! --- source/blender/blenlib/BLI_string_utf8.h | 1 + source/blender/blenlib/intern/string_utf8.c | 27 +++++++++++---- .../blender/editors/interface/interface_widgets.c | 2 ++ source/blender/editors/space_text/text_draw.c | 38 +++++++++++----------- source/blender/editors/space_text/text_ops.c | 14 ++++---- 5 files changed, 49 insertions(+), 33 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h index 73f138a750d..ecbc4cb1cd4 100644 --- a/source/blender/blenlib/BLI_string_utf8.h +++ b/source/blender/blenlib/BLI_string_utf8.h @@ -37,6 +37,7 @@ 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 */ +int BLI_str_utf8_size_safe(const char *p); /* copied from glib */ unsigned int BLI_str_utf8_as_unicode(const char *p); unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index); diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index 0b737e0eff5..e80f96ee0fe 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -317,12 +317,12 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst_w, const char *src_c, const size /* end wchar_t / utf8 functions */ /* --------------------------------------------------------------------------*/ -/* copied from glib's gutf8.c */ +/* copied from glib's gutf8.c, added 'Err' arg */ /* note, glib uses unsigned int for unicode, best we do the same, * though we don't typedef it - campbell */ -#define UTF8_COMPUTE(Char, Mask, Len) \ +#define UTF8_COMPUTE(Char, Mask, Len, Err) \ if (Char < 128) { \ Len = 1; \ Mask = 0x7f; \ @@ -348,7 +348,7 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst_w, const char *src_c, const size Mask = 0x01; \ } \ else { \ - Len = -1; \ + Len = Err; /* -1 is the typical error value or 1 to skip */ \ } (void)0 /* same as glib define but added an 'Err' arg */ @@ -371,7 +371,20 @@ int BLI_str_utf8_size(const char *p) int mask = 0, len; unsigned char c = (unsigned char) *p; - UTF8_COMPUTE (c, mask, len); + UTF8_COMPUTE (c, mask, len, -1); + + (void)mask; /* quiet warning */ + + return len; +} + +/* use when we want to skip errors */ +int BLI_str_utf8_size_safe(const char *p) +{ + int mask = 0, len; + unsigned char c = (unsigned char) *p; + + UTF8_COMPUTE (c, mask, len, 1); (void)mask; /* quiet warning */ @@ -397,7 +410,7 @@ unsigned int BLI_str_utf8_as_unicode(const char *p) unsigned int result; unsigned char c = (unsigned char) *p; - UTF8_COMPUTE (c, mask, len); + UTF8_COMPUTE (c, mask, len, -1); if (len == -1) return BLI_UTF8_ERR; UTF8_GET (result, p, i, mask, len, BLI_UTF8_ERR); @@ -412,7 +425,7 @@ unsigned int BLI_str_utf8_as_unicode_and_size(const char *p, size_t *index) unsigned int result; unsigned char c = (unsigned char) *p; - UTF8_COMPUTE (c, mask, len); + UTF8_COMPUTE (c, mask, len, -1); if (len == -1) return BLI_UTF8_ERR; UTF8_GET (result, p, i, mask, len, BLI_UTF8_ERR); @@ -431,7 +444,7 @@ unsigned int BLI_str_utf8_as_unicode_step(const char *p, size_t *index) p += *index; c = (unsigned char) *p; - UTF8_COMPUTE (c, mask, len); + UTF8_COMPUTE (c, mask, len, -1); if (len == -1) { /* when called with NULL end, result will never be NULL, * checks for a NULL character */ diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index f41abce947e..d16169f1034 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1044,6 +1044,8 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect) ui_text_clip_give_prev_off(but); len = strlen(but->drawstr); bytes = BLI_str_utf8_size(BLI_str_find_prev_char_utf8(but->drawstr, but->drawstr + len)); + if (bytes < 0) + bytes = 1; but->drawstr[len - bytes] = 0; } diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 94f64563fd8..f463b015bf5 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -95,7 +95,7 @@ static int text_font_draw_character(SpaceText *st, int x, int y, char c) static int text_font_draw_character_utf8(SpaceText *st, int x, int y, const char *c) { char str[BLI_UTF8_MAX + 1]; - size_t len = BLI_str_utf8_size(c); + size_t len = BLI_str_utf8_size_safe(c); memcpy(str, c, len); str[len] = '\0'; @@ -158,7 +158,7 @@ int flatten_string(SpaceText *st, FlattenString *fs, const char *in) in++; } else { - size_t len = BLI_str_utf8_size(in); + size_t len = BLI_str_utf8_size_safe(in); flatten_string_append(fs, in, r, len); in += len; total++; @@ -342,7 +342,7 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next) if (*str == '\\') { *fmt = prev; fmt++; str++; if (*str == '\0') break; - *fmt = prev; fmt++; str += BLI_str_utf8_size(str); + *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str); continue; } /* Handle continuations */ @@ -363,14 +363,14 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next) } *fmt = 'l'; - str += BLI_str_utf8_size(str) - 1; + str += BLI_str_utf8_size_safe(str) - 1; } /* Not in a string... */ else { /* Deal with comments first */ if (prev == '#' || *str == '#') { *fmt = '#'; - str += BLI_str_utf8_size(str) - 1; + str += BLI_str_utf8_size_safe(str) - 1; } else if (*str == '"' || *str == '\'') { /* Strings */ @@ -399,7 +399,7 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next) *fmt = 'n'; } else { - str += BLI_str_utf8_size(str) - 1; + str += BLI_str_utf8_size_safe(str) - 1; *fmt = 'q'; } /* Punctuation */ @@ -407,7 +407,7 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next) *fmt = '!'; /* Identifiers and other text (no previous ws. or delims. so text continues) */ else if (prev == 'q') { - str += BLI_str_utf8_size(str) - 1; + str += BLI_str_utf8_size_safe(str) - 1; *fmt = 'q'; } /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */ @@ -427,7 +427,7 @@ static void txt_format_line(SpaceText *st, TextLine *line, int do_next) *fmt = prev; } else { - str += BLI_str_utf8_size(str) - 1; + str += BLI_str_utf8_size_safe(str) - 1; *fmt = 'q'; } } @@ -575,7 +575,7 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int * end = max; chop = 1; *offc = 0; - for (i = 0, j = 0; linep->line[j]; j += BLI_str_utf8_size(linep->line + j)) { + for (i = 0, j = 0; linep->line[j]; j += BLI_str_utf8_size_safe(linep->line + j)) { int chars; /* Mimic replacement of tabs */ @@ -640,7 +640,7 @@ void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursi *offc = 0; cursin = txt_utf8_offset_to_index(linein->line, cursin); - for (i = 0, j = 0; linein->line[j]; j += BLI_str_utf8_size(linein->line + j)) { + for (i = 0, j = 0; linein->line[j]; j += BLI_str_utf8_size_safe(linein->line + j)) { /* Mimic replacement of tabs */ ch = linein->line[j]; @@ -685,7 +685,7 @@ int text_get_char_pos(SpaceText *st, const char *line, int cur) { int a = 0, i; - for (i = 0; i < cur && line[i]; i += BLI_str_utf8_size(line + i)) { + for (i = 0; i < cur && line[i]; i += BLI_str_utf8_size_safe(line + i)) { if (line[i] == '\t') a += st->tabnumber - a % st->tabnumber; else @@ -698,7 +698,7 @@ static const char *txt_utf8_get_nth(const char *str, int n) { int pos = 0; while (str[pos] && n--) { - pos += BLI_str_utf8_size(str + pos); + pos += BLI_str_utf8_size_safe(str + pos); } return str + pos; } @@ -719,7 +719,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w start = 0; mstart = 0; end = max; mend = txt_utf8_get_nth(str, max) - str; - for (i = 0, mi = 0; str[mi]; i++, mi += BLI_str_utf8_size(str + mi)) { + for (i = 0, mi = 0; str[mi]; i++, mi += BLI_str_utf8_size_safe(str + mi)) { if (i - start >= max) { /* skip hidden part of line */ if (skip) { @@ -730,7 +730,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w } /* Draw the visible portion of text on the overshot line */ - for (a = start, ma = mstart; a < end; a++, ma += BLI_str_utf8_size(str + ma)) { + for (a = start, ma = mstart; a < end; a++, ma += BLI_str_utf8_size_safe(str + ma)) { if (st->showsyntax && format) format_draw_color(format[a]); x += text_font_draw_character_utf8(st, x, y, str + ma); } @@ -748,7 +748,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w } /* Draw the remaining text */ - for (a = start, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size(str + ma)) { + for (a = start, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) { if (st->showsyntax && format) format_draw_color(format[a]); @@ -786,7 +786,7 @@ static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int dra for (a = 0; a < amount; a++) { format_draw_color(format[a]); x += text_font_draw_character_utf8(st, x, y, in + str_shift); - str_shift += BLI_str_utf8_size(in + str_shift); + str_shift += BLI_str_utf8_size_safe(in + str_shift); } } else text_font_draw(st, x, y, in); @@ -1016,7 +1016,7 @@ int text_get_visible_lines(SpaceText *st, ARegion *ar, const char *str) lines = 1; start = 0; end = max; - for (i = 0, j = 0; str[j]; j += BLI_str_utf8_size(str + j)) { + for (i = 0, j = 0; str[j]; j += BLI_str_utf8_size_safe(str + j)) { /* Mimic replacement of tabs */ ch = str[j]; if (ch == '\t') { @@ -1639,7 +1639,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar) if (b > 0) { /* opening bracket, search forward for close */ fc++; - c += BLI_str_utf8_size(linep->line + c); + c += BLI_str_utf8_size_safe(linep->line + c); while (linep) { while (c < linep->len) { if (linep->format && linep->format[fc] != 'l' && linep->format[fc] != '#') { @@ -1657,7 +1657,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar) } } fc++; - c += BLI_str_utf8_size(linep->line + c); + c += BLI_str_utf8_size_safe(linep->line + c); } if (endl) break; linep = linep->next; diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 2d902c4586a..1be50a54b68 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -1503,7 +1503,7 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int end = max; chop = loop = 1; - for (i = 0, j = 0; loop; j += BLI_str_utf8_size(linein->line + j)) { + for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe(linein->line + j)) { int chars; /* Mimic replacement of tabs */ ch = linein->line[j]; @@ -1682,7 +1682,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel) chop = loop = 1; *charp = 0; - for (i = 0, j = 0; loop; j += BLI_str_utf8_size((*linep)->line + j)) { + for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe((*linep)->line + j)) { int chars; /* Mimic replacement of tabs */ ch = (*linep)->line[j]; @@ -1750,7 +1750,7 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel) chop = loop = 1; *charp = 0; - for (i = 0, j = 0; loop; j += BLI_str_utf8_size((*linep)->line + j)) { + for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe((*linep)->line + j)) { int chars; /* Mimic replacement of tabs */ ch = (*linep)->line[j]; @@ -2462,7 +2462,7 @@ static int flatten_len(SpaceText *st, const char *str) { int i, total = 0; - for (i = 0; str[i]; i += BLI_str_utf8_size(str + i)) { + for (i = 0; str[i]; i += BLI_str_utf8_size_safe(str + i)) { if (str[i] == '\t') { total += st->tabnumber - total % st->tabnumber; } @@ -2475,7 +2475,7 @@ static int flatten_len(SpaceText *st, const char *str) static int flatten_index_to_offset(SpaceText *st, const char *str, int index) { int i, j; - for (i = 0, j = 0; i < index; j += BLI_str_utf8_size(str + j)) + for (i = 0, j = 0; i < index; j += BLI_str_utf8_size_safe(str + j)) if (str[j] == '\t') i += st->tabnumber - i % st->tabnumber; else @@ -2519,7 +2519,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in int j = 0, curs = 0, endj = 0; /* mem */ int chop = 1; /* flags */ - for (; loop; j += BLI_str_utf8_size(linep->line + j)) { + for (; loop; j += BLI_str_utf8_size_safe(linep->line + j)) { int chars; /* Mimic replacement of tabs */ @@ -2945,7 +2945,7 @@ static int text_insert_invoke(bContext *C, wmOperator *op, wmEvent *event) size_t len; if (event->utf8_buf[0]) { - len = BLI_str_utf8_size(event->utf8_buf); + len = BLI_str_utf8_size_safe(event->utf8_buf); memcpy(str, event->utf8_buf, len); } else { -- cgit v1.2.3