[PATCH v2] gdi32: Limit GetGlyphOutlineW(uChar) to a WORD.

Huw Davies huw at codeweavers.com
Wed Sep 23 03:41:19 CDT 2020


On 22 Sep 2020, at 13:39, Arkadiusz Hiler <ahiler at codeweavers.com> wrote:
> diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
> index e099bec5e81..0fa1722d621 100644
> --- a/dlls/gdi32/font.c
> +++ b/dlls/gdi32/font.c
> @@ -2905,6 +2905,8 @@ DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
>     dc = get_dc_ptr(hdc);
>     if(!dc) return GDI_ERROR;
> 
> +    uChar &= 0xFFFF;
> +

I think it's safe to assume that this shouldn't happen
if GGO_GLYPH_INDEX is specified.


>     dev = GET_DC_PHYSDEV( dc, pGetGlyphOutline );
>     ret = dev->funcs->pGetGlyphOutline( dev, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
>     release_dc_ptr( dc );
> diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
> index f5c8d4dac3b..6410778c0e0 100644
> --- a/dlls/gdi32/tests/font.c
> +++ b/dlls/gdi32/tests/font.c
> @@ -5800,6 +5800,58 @@ todo_wine
>     ReleaseDC(NULL, hdc);
> }
> 
> +static void test_GetGlyphOutlineW_character_limited_to_a_word(void)
> +{
> +    HFONT hfont, hfont_old;
> +    LOGFONTA lf;
> +    HDC hdc;
> +    DWORD ret;
> +    GLYPHMETRICS gm1, gm2, gmn;
> +    char test_chars[] = { 'A', 'D', '!', '\0' };
> +
> +    memset(&lf, 0, sizeof(lf));
> +    lf.lfHeight = 72;
> +    lstrcpyA(lf.lfFaceName, "wine_test");
> +
> +    hfont = CreateFontIndirectA(&lf);
> +    ok(hfont != 0, "CreateFontIndirectA error %u\n", GetLastError());
> +
> +    hdc = GetDC(NULL);
> +
> +    hfont_old = SelectObject(hdc, hfont);
> +    ok(hfont_old != NULL, "SelectObject failed\n");
> +
> +    ret = GetGlyphOutlineW(hdc, 'Z', GGO_METRICS, &gmn, 0, NULL, &mat); /* .notdef */
> +    ok(ret != GDI_ERROR, "GetGlyphOutlineW failed with %d, lest error %d\n", ret, GetLastError());
> +
> +    for (char *current_char = test_chars; *current_char != '\0'; current_char++)
> +    {
> +        ret = GetGlyphOutlineW(hdc, *current_char, GGO_METRICS, &gm1, 0, NULL, &mat);
> +        ok(ret != GDI_ERROR, "GetGlyphOutlineW failed with %d, lest error %d\n", ret, GetLastError());
> +
> +        /* make sure we differ from .notdef */
> +        ok(memcmp(&gm1, &gmn, sizeof(gmn)) != 0, "one of the test characters matches .notdef\n");
> +
> +        for (UINT offset = 0x10000; offset < 0xF0FF0000; offset += 0x1000000)

Just testing with offset = 0x10000 will be fine.

> +        {
> +            ret = GetGlyphOutlineW(hdc, offset + *current_char, GGO_METRICS, &gm2, 0, NULL, &mat);
> +            ok(ret != GDI_ERROR, "GetGlyphOutlineW failed with %d, lest error %d\n", ret, GetLastError());
> +
> +            ok(gm1.gmBlackBoxX == gm2.gmBlackBoxX, "gmBlackBoxX differs, %d should equal %d\n", gm1.gmBlackBoxX, gm2.gmBlackBoxX);
> +            ok(gm1.gmBlackBoxY == gm2.gmBlackBoxY, "gmBlackBoxY differs, %d should equal %d\n", gm1.gmBlackBoxY, gm2.gmBlackBoxY);
> +            ok(gm1.gmptGlyphOrigin.x == gm2.gmptGlyphOrigin.x, "gmptGlyphOrigin.x differs, %d should equal %d\n", gm1.gmptGlyphOrigin.x, gm2.gmptGlyphOrigin.x);
> +            ok(gm1.gmptGlyphOrigin.y == gm2.gmptGlyphOrigin.y, "gmptGlyphOrigin.y difference, %d should equal %d\n", gm1.gmptGlyphOrigin.y, gm2.gmptGlyphOrigin.y);
> +            ok(gm1.gmCellIncX == gm2.gmCellIncX, "gmCellIncX differs, %d should equal %d\n", gm1.gmCellIncX, gm2.gmCellIncX);
> +            ok(gm1.gmCellIncY == gm2.gmCellIncY, "gmCellIncY differs, %d should equal %d\n", gm1.gmCellIncY, gm2.gmCellIncY);
> +        }
> +    }
> +
> +    SelectObject(hdc, hfont_old);
> +    DeleteObject(hfont);
> +
> +    DeleteDC(hdc);

ReleaseDC()


Huw.




More information about the wine-devel mailing list