fix [#33121] crashing when srolling down in text editor !
This commit is contained in:
		@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user