mirror of
https://github.com/lvgl/lvgl.git
synced 2026-03-23 22:39:09 +08:00
fix(tiny_ttf): stream position and file read race condition (#9862)
This commit is contained in:
@@ -32,17 +32,20 @@
|
||||
#define STBTT_STREAM_TYPE ttf_cb_stream_t *
|
||||
#define STBTT_STREAM_SEEK(s, x) ttf_cb_stream_seek(s, x);
|
||||
#define STBTT_STREAM_READ(s, x, y) ttf_cb_stream_read(s, x, y);
|
||||
#define STBTT_STREAM_SEEK_AND_READ(s, o, x, y) ttf_cb_stream_seek_and_read(s,o, x, y);
|
||||
|
||||
/* a hydra stream that can be in memory or from a file*/
|
||||
typedef struct ttf_cb_stream {
|
||||
lv_fs_file_t * file;
|
||||
const void * data;
|
||||
lv_mutex_t mutex;
|
||||
size_t size;
|
||||
size_t position;
|
||||
} ttf_cb_stream_t;
|
||||
|
||||
static void ttf_cb_stream_read(ttf_cb_stream_t * stream, void * data, size_t to_read);
|
||||
static void ttf_cb_stream_seek(ttf_cb_stream_t * stream, size_t position);
|
||||
static void ttf_cb_stream_seek_and_read(ttf_cb_stream_t * stream, size_t position, void * data, size_t to_read);
|
||||
#endif
|
||||
|
||||
#include "stb_rect_pack.h"
|
||||
@@ -188,9 +191,12 @@ void lv_tiny_ttf_destroy(lv_font_t * font)
|
||||
if(font->dsc != NULL) {
|
||||
ttf_font_desc_t * ttf = (ttf_font_desc_t *)font->dsc;
|
||||
#if LV_TINY_TTF_FILE_SUPPORT != 0
|
||||
lv_mutex_lock(&ttf->stream.mutex);
|
||||
if(ttf->stream.file != NULL) {
|
||||
lv_fs_close(&ttf->file);
|
||||
}
|
||||
lv_mutex_unlock(&ttf->stream.mutex);
|
||||
lv_mutex_delete(&ttf->stream.mutex);
|
||||
#endif
|
||||
lv_cache_destroy(ttf->glyph_cache, NULL);
|
||||
lv_cache_destroy(ttf->draw_data_cache, NULL);
|
||||
@@ -235,6 +241,16 @@ static void ttf_cb_stream_seek(ttf_cb_stream_t * stream, size_t position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ttf_cb_stream_seek_and_read(ttf_cb_stream_t * stream, size_t position, void * data, size_t to_read)
|
||||
{
|
||||
lv_mutex_lock(&stream->mutex);
|
||||
|
||||
ttf_cb_stream_seek(stream, position);
|
||||
ttf_cb_stream_read(stream, data, to_read);
|
||||
|
||||
lv_mutex_unlock(&stream->mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint16_t ttf_calculate_kerning_width(float scale, uint16_t adv_w, int k)
|
||||
@@ -446,6 +462,7 @@ static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size
|
||||
return NULL;
|
||||
}
|
||||
#if LV_TINY_TTF_FILE_SUPPORT != 0
|
||||
lv_mutex_init(&dsc->stream.mutex);
|
||||
if(path != NULL) {
|
||||
if(LV_FS_RES_OK != lv_fs_open(&dsc->file, path, LV_FS_MODE_RD)) {
|
||||
lv_free(dsc);
|
||||
|
||||
@@ -450,6 +450,12 @@ typedef char stbtt__check_size16[sizeof(stbtt_int16) == 2 ? 1 : -1];
|
||||
#define STBTT_STREAM_TYPE FILE*
|
||||
#define STBTT_STREAM_READ(s,x,y) fread(x,1,y,s);
|
||||
#define STBTT_STREAM_SEEK(s,x) fseek(s,x,SEEK_SET);
|
||||
#define STBTT_STREAM_SEEK_AND_READ(s,o,x,y) (fseek(s,o,SEEK_SET), fread(x,1,y,s))
|
||||
#endif
|
||||
|
||||
#ifndef STBTT_STREAM_SEEK_AND_READ
|
||||
#define STBTT_STREAM_SEEK_AND_READ(s,o,x,y) \
|
||||
do { STBTT_STREAM_SEEK(s,o); STBTT_STREAM_READ(s,x,y); } while(0)
|
||||
#endif
|
||||
|
||||
// heap factor sizes for various counts of objects
|
||||
@@ -1190,9 +1196,8 @@ static stbtt_uint8 stbtt__buf_get8(stbtt__buf * b)
|
||||
return 0;
|
||||
#ifdef STBTT_STREAM_TYPE
|
||||
long pos = (long)(b->cursor + b->offset);
|
||||
STBTT_STREAM_SEEK(b->data, pos);
|
||||
stbtt_uint8 result;
|
||||
STBTT_STREAM_READ(b->data, &result, 1);
|
||||
STBTT_STREAM_SEEK_AND_READ(b->data, pos, &result, 1);
|
||||
++b->cursor;
|
||||
return result;
|
||||
#else
|
||||
@@ -1207,9 +1212,8 @@ static stbtt_uint8 stbtt__buf_peek8(stbtt__buf * b)
|
||||
return 0;
|
||||
#ifdef STBTT_STREAM_TYPE
|
||||
long pos = (long)(b->cursor + b->offset);
|
||||
STBTT_STREAM_SEEK(b->data, pos);
|
||||
stbtt_uint8 result;
|
||||
STBTT_STREAM_READ(b->data, &result, 1);
|
||||
STBTT_STREAM_SEEK_AND_READ(b->data, pos, &result, 1);
|
||||
return result;
|
||||
#else
|
||||
return b->data[b->cursor];
|
||||
@@ -1370,38 +1374,33 @@ static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i)
|
||||
#ifdef STBTT_STREAM_TYPE
|
||||
static stbtt_uint8 ttBYTE(STBTT_STREAM_TYPE s, stbtt_uint32 offset)
|
||||
{
|
||||
STBTT_STREAM_SEEK(s, offset);
|
||||
stbtt_uint8 r;
|
||||
STBTT_STREAM_READ(s, &r, 1);
|
||||
STBTT_STREAM_SEEK_AND_READ(s, offset, &r, 1);
|
||||
return r;
|
||||
}
|
||||
#define ttCHAR(s, offset) ((stbtt_int8)ttBYTE(s,offset))
|
||||
static stbtt_uint16 ttUSHORT(STBTT_STREAM_TYPE s, stbtt_uint32 offset)
|
||||
{
|
||||
STBTT_STREAM_SEEK(s, offset);
|
||||
stbtt_uint8 r[2];
|
||||
STBTT_STREAM_READ(s, &r, 2);
|
||||
STBTT_STREAM_SEEK_AND_READ(s, offset, r, 2);
|
||||
return r[0] * 256 + r[1];
|
||||
}
|
||||
static stbtt_int16 ttSHORT(STBTT_STREAM_TYPE s, stbtt_uint32 offset)
|
||||
{
|
||||
STBTT_STREAM_SEEK(s, offset);
|
||||
stbtt_uint8 r[2];
|
||||
STBTT_STREAM_READ(s, &r, 2);
|
||||
STBTT_STREAM_SEEK_AND_READ(s, offset, r, 2);
|
||||
return r[0] * 256 + r[1];
|
||||
}
|
||||
static stbtt_uint32 ttULONG(STBTT_STREAM_TYPE s, stbtt_uint32 offset)
|
||||
{
|
||||
STBTT_STREAM_SEEK(s, offset);
|
||||
stbtt_uint8 r[4];
|
||||
STBTT_STREAM_READ(s, &r, 4);
|
||||
STBTT_STREAM_SEEK_AND_READ(s, offset, r, 4);
|
||||
return (r[0] << 24) + (r[1] << 16) + (r[2] << 8) + r[3];
|
||||
}
|
||||
static stbtt_int32 ttLONG(STBTT_STREAM_TYPE s, stbtt_uint32 offset)
|
||||
{
|
||||
STBTT_STREAM_SEEK(s, offset);
|
||||
stbtt_uint8 r[4];
|
||||
STBTT_STREAM_READ(s, &r, 4);
|
||||
STBTT_STREAM_SEEK_AND_READ(s, offset, r, 4);
|
||||
return (r[0] << 24) + (r[1] << 16) + (r[2] << 8) + r[3];
|
||||
}
|
||||
#else
|
||||
@@ -1436,8 +1435,7 @@ static stbtt_int32 ttLONG(const stbtt_uint8 * p, stbtt_uint32 offset)
|
||||
{
|
||||
#ifdef STBTT_STREAM_TYPE
|
||||
stbtt_uint8 font[4];
|
||||
STBTT_STREAM_SEEK(stream, offs);
|
||||
STBTT_STREAM_READ(stream, font, 4);
|
||||
STBTT_STREAM_SEEK_AND_READ(stream, offs, font, 4);
|
||||
#else
|
||||
font += offs;
|
||||
#endif
|
||||
@@ -1464,8 +1462,7 @@ static stbtt_int32 ttLONG(const stbtt_uint8 * p, stbtt_uint32 offset)
|
||||
stbtt_uint32 loc = tabledir + 16 * i;
|
||||
#ifdef STBTT_STREAM_TYPE
|
||||
stbtt_uint8 buf[4];
|
||||
STBTT_STREAM_SEEK(data, loc + 0);
|
||||
STBTT_STREAM_READ(data, buf, 4);
|
||||
STBTT_STREAM_SEEK_AND_READ(data, loc, buf, 4);
|
||||
if(stbtt_tag(buf, tag))
|
||||
return ttULONG(data, loc + 8);
|
||||
#else
|
||||
@@ -1488,8 +1485,7 @@ static stbtt_int32 ttLONG(const stbtt_uint8 * p, stbtt_uint32 offset)
|
||||
// check if it's a TTC
|
||||
#ifdef STBTT_STREAM_TYPE
|
||||
stbtt_uint8 buf[4];
|
||||
STBTT_STREAM_SEEK(font_collection, 0);
|
||||
STBTT_STREAM_READ(font_collection, buf, 4);
|
||||
STBTT_STREAM_SEEK_AND_READ(font_collection, 0, buf, 4);
|
||||
if(stbtt_tag(buf, "ttcf")) {
|
||||
#else
|
||||
if(stbtt_tag(font_collection, "ttcf")) {
|
||||
@@ -1517,8 +1513,7 @@ static stbtt_int32 ttLONG(const stbtt_uint8 * p, stbtt_uint32 offset)
|
||||
// check if it's a TTC
|
||||
#ifdef STBTT_STREAM_TYPE
|
||||
stbtt_uint8 buf[4];
|
||||
STBTT_STREAM_SEEK(font_collection, 0);
|
||||
STBTT_STREAM_READ(font_collection, buf, 4);
|
||||
STBTT_STREAM_SEEK_AND_READ(font_collection, 0, buf, 4);
|
||||
if(stbtt_tag(buf, "ttcf")) {
|
||||
#else
|
||||
if(stbtt_tag(font_collection, "ttcf")) {
|
||||
|
||||
Reference in New Issue
Block a user