dwrite: Validate 'gasp' data before accessing it.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2dcb3c7451
commit
471611b575
|
@ -254,7 +254,7 @@ enum gasp_flags {
|
||||||
GASP_SYMMETRIC_SMOOTHING = 0x0008,
|
GASP_SYMMETRIC_SMOOTHING = 0x0008,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern WORD opentype_get_gasp_flags(const WORD*,UINT32,INT) DECLSPEC_HIDDEN;
|
extern unsigned int opentype_get_gasp_flags(const struct dwrite_fonttable *gasp, float emsize) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* BiDi helpers */
|
/* BiDi helpers */
|
||||||
extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLSPEC_HIDDEN;
|
extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -379,11 +379,10 @@ static const void* get_fontface_vdmx(struct dwrite_fontface *fontface)
|
||||||
return get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_VDMX_TAG, &fontface->vdmx);
|
return get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_VDMX_TAG, &fontface->vdmx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const void* get_fontface_gasp(struct dwrite_fontface *fontface, UINT32 *size)
|
static const struct dwrite_fonttable *get_fontface_gasp(struct dwrite_fontface *fontface)
|
||||||
{
|
{
|
||||||
const void *ptr = get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_GASP_TAG, &fontface->gasp);
|
get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_GASP_TAG, &fontface->gasp);
|
||||||
*size = fontface->gasp.size;
|
return &fontface->gasp;
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const void* get_fontface_cpal(struct dwrite_fontface *fontface)
|
static const void* get_fontface_cpal(struct dwrite_fontface *fontface)
|
||||||
|
@ -687,7 +686,7 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace4 *iface,
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWRITE_RENDERING_MODE fontface_renderingmode_from_measuringmode(DWRITE_MEASURING_MODE measuring,
|
static DWRITE_RENDERING_MODE fontface_renderingmode_from_measuringmode(DWRITE_MEASURING_MODE measuring,
|
||||||
FLOAT ppem, WORD gasp)
|
float ppem, unsigned int gasp)
|
||||||
{
|
{
|
||||||
DWRITE_RENDERING_MODE mode = DWRITE_RENDERING_MODE_DEFAULT;
|
DWRITE_RENDERING_MODE mode = DWRITE_RENDERING_MODE_DEFAULT;
|
||||||
|
|
||||||
|
@ -718,10 +717,8 @@ static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace
|
||||||
FLOAT ppdip, DWRITE_MEASURING_MODE measuring, IDWriteRenderingParams *params, DWRITE_RENDERING_MODE *mode)
|
FLOAT ppdip, DWRITE_MEASURING_MODE measuring, IDWriteRenderingParams *params, DWRITE_RENDERING_MODE *mode)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
|
struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
|
||||||
const WORD *ptr;
|
unsigned int flags;
|
||||||
UINT32 size;
|
|
||||||
FLOAT ppem;
|
FLOAT ppem;
|
||||||
WORD gasp;
|
|
||||||
|
|
||||||
TRACE("(%p)->(%.2f %.2f %d %p %p)\n", This, emSize, ppdip, measuring, params, mode);
|
TRACE("(%p)->(%.2f %.2f %d %p %p)\n", This, emSize, ppdip, measuring, params, mode);
|
||||||
|
|
||||||
|
@ -741,9 +738,8 @@ static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = get_fontface_gasp(This, &size);
|
flags = opentype_get_gasp_flags(get_fontface_gasp(This), ppem);
|
||||||
gasp = opentype_get_gasp_flags(ptr, size, ppem);
|
*mode = fontface_renderingmode_from_measuringmode(measuring, ppem, flags);
|
||||||
*mode = fontface_renderingmode_from_measuringmode(measuring, ppem, gasp);
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1097,10 +1093,8 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac
|
||||||
DWRITE_GRID_FIT_MODE *gridfitmode)
|
DWRITE_GRID_FIT_MODE *gridfitmode)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
|
struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
|
||||||
|
unsigned int flags;
|
||||||
FLOAT emthreshold;
|
FLOAT emthreshold;
|
||||||
const WORD *ptr;
|
|
||||||
UINT32 size;
|
|
||||||
WORD gasp;
|
|
||||||
|
|
||||||
TRACE("(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)\n", This, emSize, dpiX, dpiY, m, is_sideways, threshold,
|
TRACE("(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)\n", This, emSize, dpiX, dpiY, m, is_sideways, threshold,
|
||||||
measuringmode, params, renderingmode, gridfitmode);
|
measuringmode, params, renderingmode, gridfitmode);
|
||||||
|
@ -1131,14 +1125,13 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac
|
||||||
|
|
||||||
emthreshold = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? RECOMMENDED_OUTLINE_AA_THRESHOLD : RECOMMENDED_OUTLINE_A_THRESHOLD;
|
emthreshold = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? RECOMMENDED_OUTLINE_AA_THRESHOLD : RECOMMENDED_OUTLINE_A_THRESHOLD;
|
||||||
|
|
||||||
ptr = get_fontface_gasp(This, &size);
|
flags = opentype_get_gasp_flags(get_fontface_gasp(This), emSize);
|
||||||
gasp = opentype_get_gasp_flags(ptr, size, emSize);
|
|
||||||
|
|
||||||
if (*renderingmode == DWRITE_RENDERING_MODE_DEFAULT) {
|
if (*renderingmode == DWRITE_RENDERING_MODE_DEFAULT) {
|
||||||
if (emSize >= emthreshold)
|
if (emSize >= emthreshold)
|
||||||
*renderingmode = DWRITE_RENDERING_MODE_OUTLINE;
|
*renderingmode = DWRITE_RENDERING_MODE_OUTLINE;
|
||||||
else
|
else
|
||||||
*renderingmode = fontface_renderingmode_from_measuringmode(measuringmode, emSize, gasp);
|
*renderingmode = fontface_renderingmode_from_measuringmode(measuringmode, emSize, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*gridfitmode == DWRITE_GRID_FIT_MODE_DEFAULT) {
|
if (*gridfitmode == DWRITE_GRID_FIT_MODE_DEFAULT) {
|
||||||
|
@ -1147,7 +1140,8 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac
|
||||||
else if (measuringmode == DWRITE_MEASURING_MODE_GDI_CLASSIC || measuringmode == DWRITE_MEASURING_MODE_GDI_NATURAL)
|
else if (measuringmode == DWRITE_MEASURING_MODE_GDI_CLASSIC || measuringmode == DWRITE_MEASURING_MODE_GDI_NATURAL)
|
||||||
*gridfitmode = DWRITE_GRID_FIT_MODE_ENABLED;
|
*gridfitmode = DWRITE_GRID_FIT_MODE_ENABLED;
|
||||||
else
|
else
|
||||||
*gridfitmode = (gasp & (GASP_GRIDFIT|GASP_SYMMETRIC_GRIDFIT)) ? DWRITE_GRID_FIT_MODE_ENABLED : DWRITE_GRID_FIT_MODE_DISABLED;
|
*gridfitmode = flags & (GASP_GRIDFIT|GASP_SYMMETRIC_GRIDFIT) ?
|
||||||
|
DWRITE_GRID_FIT_MODE_ENABLED : DWRITE_GRID_FIT_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -1229,10 +1223,8 @@ static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFac
|
||||||
IDWriteRenderingParams *params, DWRITE_RENDERING_MODE1 *rendering_mode, DWRITE_GRID_FIT_MODE *gridfit_mode)
|
IDWriteRenderingParams *params, DWRITE_RENDERING_MODE1 *rendering_mode, DWRITE_GRID_FIT_MODE *gridfit_mode)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
|
struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
|
||||||
|
unsigned int flags;
|
||||||
FLOAT emthreshold;
|
FLOAT emthreshold;
|
||||||
const WORD *ptr;
|
|
||||||
UINT32 size;
|
|
||||||
WORD gasp;
|
|
||||||
|
|
||||||
TRACE("(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)\n", This, emSize, dpiX, dpiY, m, is_sideways, threshold,
|
TRACE("(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)\n", This, emSize, dpiX, dpiY, m, is_sideways, threshold,
|
||||||
measuring_mode, params, rendering_mode, gridfit_mode);
|
measuring_mode, params, rendering_mode, gridfit_mode);
|
||||||
|
@ -1263,14 +1255,13 @@ static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFac
|
||||||
|
|
||||||
emthreshold = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? RECOMMENDED_OUTLINE_AA_THRESHOLD : RECOMMENDED_OUTLINE_A_THRESHOLD;
|
emthreshold = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? RECOMMENDED_OUTLINE_AA_THRESHOLD : RECOMMENDED_OUTLINE_A_THRESHOLD;
|
||||||
|
|
||||||
ptr = get_fontface_gasp(This, &size);
|
flags = opentype_get_gasp_flags(get_fontface_gasp(This), emSize);
|
||||||
gasp = opentype_get_gasp_flags(ptr, size, emSize);
|
|
||||||
|
|
||||||
if (*rendering_mode == DWRITE_RENDERING_MODE1_DEFAULT) {
|
if (*rendering_mode == DWRITE_RENDERING_MODE1_DEFAULT) {
|
||||||
if (emSize >= emthreshold)
|
if (emSize >= emthreshold)
|
||||||
*rendering_mode = DWRITE_RENDERING_MODE1_OUTLINE;
|
*rendering_mode = DWRITE_RENDERING_MODE1_OUTLINE;
|
||||||
else
|
else
|
||||||
*rendering_mode = fontface_renderingmode_from_measuringmode(measuring_mode, emSize, gasp);
|
*rendering_mode = fontface_renderingmode_from_measuringmode(measuring_mode, emSize, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*gridfit_mode == DWRITE_GRID_FIT_MODE_DEFAULT) {
|
if (*gridfit_mode == DWRITE_GRID_FIT_MODE_DEFAULT) {
|
||||||
|
@ -1279,7 +1270,8 @@ static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFac
|
||||||
else if (measuring_mode == DWRITE_MEASURING_MODE_GDI_CLASSIC || measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL)
|
else if (measuring_mode == DWRITE_MEASURING_MODE_GDI_CLASSIC || measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL)
|
||||||
*gridfit_mode = DWRITE_GRID_FIT_MODE_ENABLED;
|
*gridfit_mode = DWRITE_GRID_FIT_MODE_ENABLED;
|
||||||
else
|
else
|
||||||
*gridfit_mode = (gasp & (GASP_GRIDFIT|GASP_SYMMETRIC_GRIDFIT)) ? DWRITE_GRID_FIT_MODE_ENABLED : DWRITE_GRID_FIT_MODE_DISABLED;
|
*gridfit_mode = flags & (GASP_GRIDFIT|GASP_SYMMETRIC_GRIDFIT) ?
|
||||||
|
DWRITE_GRID_FIT_MODE_ENABLED : DWRITE_GRID_FIT_MODE_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
|
@ -292,6 +292,20 @@ typedef struct {
|
||||||
BYTE bitDepth;
|
BYTE bitDepth;
|
||||||
BYTE flags;
|
BYTE flags;
|
||||||
} CBLCBitmapSizeTable;
|
} CBLCBitmapSizeTable;
|
||||||
|
|
||||||
|
struct gasp_range
|
||||||
|
{
|
||||||
|
WORD max_ppem;
|
||||||
|
WORD flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gasp_header
|
||||||
|
{
|
||||||
|
WORD version;
|
||||||
|
WORD num_ranges;
|
||||||
|
struct gasp_range ranges[1];
|
||||||
|
};
|
||||||
|
|
||||||
#include "poppack.h"
|
#include "poppack.h"
|
||||||
|
|
||||||
enum OS2_FSSELECTION {
|
enum OS2_FSSELECTION {
|
||||||
|
@ -1959,25 +1973,32 @@ BOOL opentype_get_vdmx_size(const void *data, INT emsize, UINT16 *ascent, UINT16
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
WORD opentype_get_gasp_flags(const WORD *ptr, UINT32 size, INT emsize)
|
unsigned int opentype_get_gasp_flags(const struct dwrite_fonttable *gasp, float emsize)
|
||||||
{
|
{
|
||||||
WORD num_recs, version;
|
unsigned int version, num_ranges, i;
|
||||||
|
const struct gasp_header *table;
|
||||||
WORD flags = 0;
|
WORD flags = 0;
|
||||||
|
|
||||||
if (!ptr)
|
if (!gasp->exists)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
version = GET_BE_WORD( *ptr++ );
|
num_ranges = table_read_be_word(gasp, FIELD_OFFSET(struct gasp_header, num_ranges));
|
||||||
num_recs = GET_BE_WORD( *ptr++ );
|
|
||||||
if (version > 1 || size < (num_recs * 2 + 2) * sizeof(WORD)) {
|
table = table_read_ensure(gasp, 0, FIELD_OFFSET(struct gasp_header, ranges[num_ranges]));
|
||||||
ERR("unsupported gasp table: ver %d size %d recs %d\n", version, size, num_recs);
|
if (!table)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
version = GET_BE_WORD(table->version);
|
||||||
|
if (version > 1)
|
||||||
|
{
|
||||||
|
ERR("Unsupported gasp table format version %u.\n", version);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (num_recs--) {
|
for (i = 0; i < num_ranges; ++i)
|
||||||
flags = GET_BE_WORD( *(ptr + 1) );
|
{
|
||||||
if (emsize <= GET_BE_WORD( *ptr )) break;
|
flags = GET_BE_WORD(table->ranges[i].flags);
|
||||||
ptr += 2;
|
if (emsize <= GET_BE_WORD(table->ranges[i].max_ppem)) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
Loading…
Reference in New Issue