diff --git a/libobs/util/utf8.c b/libobs/util/utf8.c index a90618ac878d0e..190524fbfea42f 100644 --- a/libobs/util/utf8.c +++ b/libobs/util/utf8.c @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include +#include #include "utf8.h" @@ -142,13 +143,10 @@ size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, total = 0; p = (unsigned char *)in; - lim = (insize != 0) ? (p + insize) : (unsigned char *)-1; + lim = p + (insize != 0 ? insize : strlen(in)); wlim = out == NULL ? NULL : out + outsize; for (; p < lim; p += n) { - if (!*p && insize == 0) - break; - if (utf8_forbidden(*p) != 0 && (flags & UTF8_IGNORE_ERROR) == 0) return 0; @@ -270,15 +268,12 @@ size_t wchar_to_utf8(const wchar_t *in, size_t insize, char *out, return 0; w = (wchar_t *)in; - wlim = (insize != 0) ? (w + insize) : (wchar_t *)-1; + wlim = w + (insize != 0 ? insize : wcslen(w)); p = (unsigned char *)out; lim = out == NULL ? NULL : p + outsize; total = 0; for (; w < wlim; w++) { - if (!*w && insize == 0) - break; - if (wchar_forbidden(*w) != 0) { if ((flags & UTF8_IGNORE_ERROR) == 0) return 0; diff --git a/plugins/text-freetype2/text-freetype2.c b/plugins/text-freetype2/text-freetype2.c index 3de3dc4c68f1cf..dd851297f384d6 100644 --- a/plugins/text-freetype2/text-freetype2.c +++ b/plugins/text-freetype2/text-freetype2.c @@ -238,6 +238,7 @@ static void ft2_source_destroy(void *data) bfree(srcdata->font_style); if (srcdata->text != NULL) bfree(srcdata->text); + srcdata->text_len = 0; if (srcdata->texbuf != NULL) bfree(srcdata->texbuf); if (srcdata->text_file != NULL) @@ -271,7 +272,8 @@ static void ft2_source_render(void *data, gs_effect_t *effect) if (srcdata->tex == NULL || srcdata->vbuf == NULL) return; - if (srcdata->text == NULL || *srcdata->text == 0) + if (srcdata->text == NULL || *srcdata->text == 0 || + srcdata->text_len == 0) return; gs_reset_blend_state(); @@ -281,7 +283,7 @@ static void ft2_source_render(void *data, gs_effect_t *effect) draw_drop_shadow(srcdata); draw_uv_vbuffer(srcdata->vbuf, srcdata->tex, srcdata->draw_effect, - (uint32_t)wcslen(srcdata->text) * 6, true); + (uint32_t)srcdata->text_len * 6, true); UNUSED_PARAMETER(effect); } @@ -304,7 +306,7 @@ static void ft2_video_tick(void *data, float seconds) else load_text_from_file(srcdata, srcdata->text_file); - cache_glyphs(srcdata, srcdata->text); + cache_glyphs(srcdata, srcdata->text, srcdata->text_len); set_up_vertex_buffer(srcdata); srcdata->update_file = false; } @@ -490,8 +492,8 @@ static void ft2_source_update(void *data, obs_data_t *settings) bfree(srcdata->text); srcdata->text = NULL; - os_utf8_to_wcs_ptr(emptystr, strlen(emptystr), - &srcdata->text); + srcdata->text_len = os_utf8_to_wcs_ptr( + emptystr, strlen(emptystr), &srcdata->text); blog(LOG_WARNING, "FT2-text: Failed to open %s for " "reading", @@ -519,13 +521,15 @@ static void ft2_source_update(void *data, obs_data_t *settings) if (srcdata->text != NULL) { bfree(srcdata->text); srcdata->text = NULL; + srcdata->text_len = 0; } - os_utf8_to_wcs_ptr(tmp, strlen(tmp), &srcdata->text); + srcdata->text_len = + os_utf8_to_wcs_ptr(tmp, strlen(tmp), &srcdata->text); } if (srcdata->font_face) { - cache_glyphs(srcdata, srcdata->text); + cache_glyphs(srcdata, srcdata->text, srcdata->text_len); set_up_vertex_buffer(srcdata); } diff --git a/plugins/text-freetype2/text-freetype2.h b/plugins/text-freetype2/text-freetype2.h index 98e404f842d944..dac94057305083 100644 --- a/plugins/text-freetype2/text-freetype2.h +++ b/plugins/text-freetype2/text-freetype2.h @@ -40,6 +40,7 @@ struct ft2_source { bool antialiasing; char *text_file; wchar_t *text; + size_t text_len; time_t m_timestamp; bool update_file; uint64_t last_checked; @@ -98,7 +99,8 @@ void load_text_from_file(struct ft2_source *srcdata, const char *filename); void read_from_end(struct ft2_source *srcdata, const char *filename); void cache_standard_glyphs(struct ft2_source *srcdata); -void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs); +void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs, + size_t cache_glyphs_len); void set_up_vertex_buffer(struct ft2_source *srcdata); void fill_vertex_buffer(struct ft2_source *srcdata); diff --git a/plugins/text-freetype2/text-functionality.c b/plugins/text-freetype2/text-functionality.c index 08eb96e72a66ad..45e83d0505b2c7 100644 --- a/plugins/text-freetype2/text-functionality.c +++ b/plugins/text-freetype2/text-functionality.c @@ -39,7 +39,7 @@ void draw_outlines(struct ft2_source *srcdata) 0.0f); draw_uv_vbuffer(srcdata->vbuf, srcdata->tex, srcdata->draw_effect, - (uint32_t)wcslen(srcdata->text) * 6, false); + (uint32_t)srcdata->text_len * 6, false); } gs_matrix_identity(); gs_matrix_pop(); @@ -53,7 +53,7 @@ void draw_drop_shadow(struct ft2_source *srcdata) gs_matrix_push(); gs_matrix_translate3f(4.0f, 4.0f, 0.0f); draw_uv_vbuffer(srcdata->vbuf, srcdata->tex, srcdata->draw_effect, - (uint32_t)wcslen(srcdata->text) * 6, false); + (uint32_t)srcdata->text_len * 6, false); gs_matrix_identity(); gs_matrix_pop(); } @@ -86,17 +86,17 @@ void set_up_vertex_buffer(struct ft2_source *srcdata) } srcdata->vbuf = - create_uv_vbuffer((uint32_t)wcslen(srcdata->text) * 6, true); + create_uv_vbuffer((uint32_t)srcdata->text_len * 6, true); if (srcdata->custom_width <= 100) goto skip_word_wrap; if (!srcdata->word_wrap) goto skip_word_wrap; - len = wcslen(srcdata->text); + len = srcdata->text_len; for (uint32_t i = 0; i <= len; i++) { - if (i == wcslen(srcdata->text)) + if (i == srcdata->text_len) goto eos_check; if (srcdata->text[i] != L' ' && srcdata->text[i] != L'\n') @@ -108,7 +108,7 @@ void set_up_vertex_buffer(struct ft2_source *srcdata) srcdata->text[space_pos] = L'\n'; x = 0; } - if (i == wcslen(srcdata->text)) + if (i == srcdata->text_len) goto eos_skip; x += word_width; @@ -145,7 +145,7 @@ void fill_vertex_buffer(struct ft2_source *srcdata) uint32_t dx = 0, dy = srcdata->max_h, max_y = dy; uint32_t cur_glyph = 0; uint32_t offset = 0; - size_t len = wcslen(srcdata->text); + size_t len = srcdata->text_len; if (srcdata->outline_text) { offset = 2; @@ -159,7 +159,7 @@ void fill_vertex_buffer(struct ft2_source *srcdata) dx = offset; i++; dy += srcdata->max_h + 4; - if (i == wcslen(srcdata->text)) + if (i == srcdata->text_len) goto skip_glyph; if (srcdata->text[i] == L'\n') goto add_linebreak; @@ -213,9 +213,11 @@ void cache_standard_glyphs(struct ft2_source *srcdata) srcdata->texbuf_x = 0; srcdata->texbuf_y = 0; - cache_glyphs(srcdata, L"abcdefghijklmnopqrstuvwxyz" - L"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" - L"!@#$%^&*()-_=+,<.>/?\\|[]{}`~ \'\"\0"); + cache_glyphs(srcdata, + L"abcdefghijklmnopqrstuvwxyz" + L"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" + L"!@#$%^&*()-_=+,<.>/?\\|[]{}`~ \'\"\0", + 0); } FT_Render_Mode get_render_mode(struct ft2_source *srcdata) @@ -290,7 +292,8 @@ void rasterize(struct ft2_source *srcdata, FT_GlyphSlot slot, } } -void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) +void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs, + size_t cache_glyphs_len) { if (!srcdata->font_face || !cache_glyphs) return; @@ -301,7 +304,8 @@ void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs) uint32_t dy = srcdata->texbuf_y; int32_t cached_glyphs = 0; - const size_t len = wcslen(cache_glyphs); + const size_t len = cache_glyphs_len == 0 ? wcslen(cache_glyphs) + : cache_glyphs_len; const FT_Render_Mode render_mode = get_render_mode(srcdata); @@ -379,15 +383,15 @@ time_t get_modified_timestamp(char *filename) return stats.st_mtime; } -static void remove_cr(wchar_t *source) +static void remove_cr(wchar_t *source, size_t *source_len) { - int j = 0; - for (int i = 0; source[i] != '\0'; ++i) { + size_t j = 0; + for (size_t i = 0; i < *source_len; ++i) { if (source[i] != L'\r') { source[j++] = source[i]; } } - source[j] = '\0'; + *source_len = j; } void load_text_from_file(struct ft2_source *srcdata, const char *filename) @@ -416,9 +420,15 @@ void load_text_from_file(struct ft2_source *srcdata, const char *filename) if (srcdata->text != NULL) { bfree(srcdata->text); srcdata->text = NULL; + srcdata->text_len = 0; + } + + // wchar_t was a mistake. + if (sizeof(wchar_t) == 2) { + srcdata->text = bzalloc(filesize); + srcdata->text_len = fread(srcdata->text, 2, + (filesize - 2) / 2, tmp_file); } - srcdata->text = bzalloc(filesize); - bytes_read = fread(srcdata->text, filesize - 2, 1, tmp_file); bfree(tmp_read); fclose(tmp_file); @@ -429,18 +439,18 @@ void load_text_from_file(struct ft2_source *srcdata, const char *filename) fseek(tmp_file, 0, SEEK_SET); tmp_read = bzalloc(filesize + 1); - bytes_read = fread(tmp_read, filesize, 1, tmp_file); + bytes_read = fread(tmp_read, 1, filesize, tmp_file); fclose(tmp_file); if (srcdata->text != NULL) { bfree(srcdata->text); srcdata->text = NULL; } - srcdata->text = bzalloc((strlen(tmp_read) + 1) * sizeof(wchar_t)); - os_utf8_to_wcs(tmp_read, strlen(tmp_read), srcdata->text, - (strlen(tmp_read) + 1)); + srcdata->text_len = os_utf8_to_wcs(tmp_read, bytes_read, NULL, 0) + 1; + srcdata->text = bzalloc(srcdata->text_len * sizeof(wchar_t)); + os_utf8_to_wcs(tmp_read, bytes_read, srcdata->text, srcdata->text_len); - remove_cr(srcdata->text); + remove_cr(srcdata->text, &srcdata->text_len); bfree(tmp_read); } @@ -501,11 +511,16 @@ void read_from_end(struct ft2_source *srcdata, const char *filename) bfree(srcdata->text); srcdata->text = NULL; } - srcdata->text = bzalloc(filesize - cur_pos); - bytes_read = - fread(srcdata->text, (filesize - cur_pos), 1, tmp_file); - remove_cr(srcdata->text); + // wchar_t was a mistake. + if (sizeof(wchar_t) == 2) { + srcdata->text = bzalloc(filesize - cur_pos); + srcdata->text_len = fread(srcdata->text, 2, + (filesize - cur_pos) / 2, + tmp_file); + } + + remove_cr(srcdata->text, &srcdata->text_len); bfree(tmp_read); fclose(tmp_file); @@ -513,18 +528,18 @@ void read_from_end(struct ft2_source *srcdata, const char *filename) } tmp_read = bzalloc((filesize - cur_pos) + 1); - bytes_read = fread(tmp_read, filesize - cur_pos, 1, tmp_file); + bytes_read = fread(tmp_read, 1, filesize - cur_pos, tmp_file); fclose(tmp_file); if (srcdata->text != NULL) { bfree(srcdata->text); srcdata->text = NULL; } - srcdata->text = bzalloc((strlen(tmp_read) + 1) * sizeof(wchar_t)); - os_utf8_to_wcs(tmp_read, strlen(tmp_read), srcdata->text, - (strlen(tmp_read) + 1)); + srcdata->text_len = os_utf8_to_wcs(tmp_read, bytes_read, NULL, 0) + 1; + srcdata->text = bzalloc(srcdata->text_len * sizeof(wchar_t)); + os_utf8_to_wcs(tmp_read, bytes_read, srcdata->text, srcdata->text_len); - remove_cr(srcdata->text); + remove_cr(srcdata->text, &srcdata->text_len); bfree(tmp_read); } @@ -536,7 +551,7 @@ uint32_t get_ft2_text_width(wchar_t *text, struct ft2_source *srcdata) FT_GlyphSlot slot = srcdata->font_face->glyph; uint32_t w = 0, max_w = 0; - const size_t len = wcslen(text); + const size_t len = srcdata->text_len; for (size_t i = 0; i < len; i++) { const FT_UInt glyph_index = FT_Get_Char_Index(srcdata->font_face, text[i]);