dwrite: Validate 'CBLC' data before using it.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1ee9685003
commit
e6967c513d
|
@ -216,6 +216,9 @@ struct dwrite_fonttable
|
||||||
BOOL exists;
|
BOOL exists;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag,
|
||||||
|
struct dwrite_fonttable *table) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,BOOL*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,UINT32*) DECLSPEC_HIDDEN;
|
extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,BOOL*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,UINT32*) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT opentype_get_font_table(struct file_stream_desc*,UINT32,const void**,void**,UINT32*,BOOL*) DECLSPEC_HIDDEN;
|
extern HRESULT opentype_get_font_table(struct file_stream_desc*,UINT32,const void**,void**,UINT32*,BOOL*) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *table, unsigned int max_count,
|
extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *table, unsigned int max_count,
|
||||||
|
|
|
@ -338,7 +338,7 @@ static HRESULT set_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag, struct dwrite_fonttable *table)
|
const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag, struct dwrite_fonttable *table)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
|
|
@ -268,17 +268,19 @@ typedef struct {
|
||||||
WORD numGlyphs;
|
WORD numGlyphs;
|
||||||
} maxp;
|
} maxp;
|
||||||
|
|
||||||
typedef struct {
|
struct cblc_header
|
||||||
WORD majorVersion;
|
{
|
||||||
WORD minorVersion;
|
WORD major_version;
|
||||||
DWORD numSizes;
|
WORD minor_version;
|
||||||
} CBLCHeader;
|
DWORD num_sizes;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BYTE res[12];
|
BYTE res[12];
|
||||||
} sbitLineMetrics;
|
} sbitLineMetrics;
|
||||||
|
|
||||||
typedef struct {
|
struct cblc_bitmapsize_table
|
||||||
|
{
|
||||||
DWORD indexSubTableArrayOffset;
|
DWORD indexSubTableArrayOffset;
|
||||||
DWORD indexTablesSize;
|
DWORD indexTablesSize;
|
||||||
DWORD numberofIndexSubTables;
|
DWORD numberofIndexSubTables;
|
||||||
|
@ -289,9 +291,9 @@ typedef struct {
|
||||||
WORD endGlyphIndex;
|
WORD endGlyphIndex;
|
||||||
BYTE ppemX;
|
BYTE ppemX;
|
||||||
BYTE ppemY;
|
BYTE ppemY;
|
||||||
BYTE bitDepth;
|
BYTE bit_depth;
|
||||||
BYTE flags;
|
BYTE flags;
|
||||||
} CBLCBitmapSizeTable;
|
};
|
||||||
|
|
||||||
struct gasp_range
|
struct gasp_range
|
||||||
{
|
{
|
||||||
|
@ -2284,36 +2286,39 @@ static DWORD opentype_get_sbix_formats(IDWriteFontFace4 *fontface)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT32 opentype_get_cblc_formats(IDWriteFontFace4 *fontface)
|
static unsigned int opentype_get_cblc_formats(IDWriteFontFace4 *fontface)
|
||||||
{
|
{
|
||||||
CBLCBitmapSizeTable *sizes;
|
const unsigned int format_mask = DWRITE_GLYPH_IMAGE_FORMATS_PNG |
|
||||||
UINT32 num_sizes, size, s;
|
DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8;
|
||||||
BOOL exists = FALSE;
|
const struct cblc_bitmapsize_table *sizes;
|
||||||
CBLCHeader *header;
|
struct dwrite_fonttable cblc = { 0 };
|
||||||
UINT32 ret = 0;
|
unsigned int num_sizes, i, ret = 0;
|
||||||
void *context;
|
const struct cblc_header *header;
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if (FAILED(hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_CBLC_TAG, (const void **)&header, &size,
|
cblc.exists = TRUE;
|
||||||
&context, &exists)))
|
if (!get_fontface_table(fontface, MS_CBLC_TAG, &cblc))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!exists)
|
num_sizes = table_read_be_dword(&cblc, FIELD_OFFSET(struct cblc_header, num_sizes));
|
||||||
return 0;
|
sizes = table_read_ensure(&cblc, sizeof(*header), num_sizes * sizeof(*sizes));
|
||||||
|
|
||||||
num_sizes = GET_BE_DWORD(header->numSizes);
|
if (sizes)
|
||||||
sizes = (CBLCBitmapSizeTable *)(header + 1);
|
{
|
||||||
|
for (i = 0; i < num_sizes; ++i)
|
||||||
|
{
|
||||||
|
BYTE bpp = sizes[i].bit_depth;
|
||||||
|
|
||||||
for (s = 0; s < num_sizes; s++) {
|
if ((ret & format_mask) == format_mask)
|
||||||
BYTE bpp = sizes->bitDepth;
|
break;
|
||||||
|
|
||||||
if (bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8)
|
if (bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8)
|
||||||
ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG;
|
ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG;
|
||||||
else if (bpp == 32)
|
else if (bpp == 32)
|
||||||
ret |= DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8;
|
ret |= DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IDWriteFontFace4_ReleaseFontTable(fontface, context);
|
IDWriteFontFace4_ReleaseFontTable(fontface, cblc.context);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8755,7 +8755,7 @@ static DWORD get_cblc_formats(IDWriteFontFace4 *fontface)
|
||||||
sizes = (CBLCBitmapSizeTable *)(header + 1);
|
sizes = (CBLCBitmapSizeTable *)(header + 1);
|
||||||
|
|
||||||
for (s = 0; s < num_sizes; s++) {
|
for (s = 0; s < num_sizes; s++) {
|
||||||
BYTE bpp = sizes->bitDepth;
|
BYTE bpp = sizes[s].bitDepth;
|
||||||
|
|
||||||
if (bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8)
|
if (bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8)
|
||||||
ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG;
|
ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG;
|
||||||
|
|
Loading…
Reference in New Issue