[PATCH v4] gdi32: ExtTextOut should fail if count is larger than INT_MAX.

Huw Davies huw at codeweavers.com
Wed Feb 3 07:36:09 CST 2021


From: Gabriel Ivăncescu <gabrielopcode at gmail.com>

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/gdi32/font.c           |  3 +++
 dlls/gdi32/tests/dib.c      | 15 +++++++++++++-
 dlls/gdi32/tests/metafile.c | 41 +++++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 74ca4825de4..de50bf0de42 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -5823,6 +5823,8 @@ BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
     BOOL ret;
     LPINT lpDxW = NULL;
 
+    if (count > INT_MAX) return FALSE;
+
     if (flags & ETO_GLYPH_INDEX)
         return ExtTextOutW( hdc, x, y, flags, lprect, (LPCWSTR)str, count, lpDx );
 
@@ -5932,6 +5934,7 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
     static int quietfixme = 0;
 
     if (!dc) return FALSE;
+    if (count > INT_MAX) return FALSE;
 
     align = dc->textAlign;
     breakRem = dc->breakRem;
diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c
index d16cb0df5c0..bdc3d9ed55b 100644
--- a/dlls/gdi32/tests/dib.c
+++ b/dlls/gdi32/tests/dib.c
@@ -3020,8 +3020,9 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa )
     static const char str[] = "Hello Wine";
     POINT origin, g_org;
     static const BYTE vals[4] = { 0x00, 0x00, 0x00, 0x00 };
+    COLORREF bk_color, text_color;
     TEXTMETRICA tm;
-    COLORREF text_color;
+    RECT rect;
 
     for(i = 0; i < dib_size; i++)
         bits[i] = vals[i % 4];
@@ -3116,6 +3117,18 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa )
     diy_hash = hash_dib( hdc, bmi, bits );
     ok( !strcmp( eto_hash, diy_hash ), "hash mismatch - aa %d\n", aa );
 
+    bk_color = GetBkColor( hdc );
+    SetBkColor( hdc, RGB(128,64,32) );
+
+    SetRect( &rect, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight );
+    ret = ExtTextOutA( hdc, 10, 100, ETO_OPAQUE, &rect, str, -1, NULL );
+    ok( !ret, "ExtTextOutA succeeded\n" );
+
+    diy_hash = hash_dib( hdc, bmi, bits );
+    ok( !strcmp( eto_hash, diy_hash ), "hash mismatch - aa %d\n", aa );
+
+    SetBkColor( hdc, bk_color );
+
     HeapFree( GetProcessHeap(), 0, diy_hash );
     HeapFree( GetProcessHeap(), 0, eto_hash );
 
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 8dae908126d..e81cff1ae57 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -2394,6 +2394,26 @@ static void test_mf_ExtTextOut_on_path(void)
     ok(ret, "DeleteMetaFile(%p) error %d\n", hMetafile, GetLastError());
 }
 
+static const unsigned char EMF_EMPTY_BITS[] =
+{
+    0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xdd, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff,
+    0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x90, 0x06, 0x00, 0x00, 0xba, 0x03, 0x00, 0x00,
+    0x4e, 0x02, 0x00, 0x00, 0x4a, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x09, 0x00,
+    0x10, 0x09, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00,
+    0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
 static void test_emf_ExtTextOut_on_path(void)
 {
     HWND hwnd;
@@ -2403,6 +2423,7 @@ static void test_emf_ExtTextOut_on_path(void)
     LOGFONTA lf;
     HFONT hFont;
     static const INT dx[4] = { 3, 5, 8, 12 };
+    RECT rect = { 10, 20, 30, 40 };
 
     /* Win9x doesn't play EMFs on invisible windows */
     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
@@ -2515,6 +2536,26 @@ static void test_emf_ExtTextOut_on_path(void)
     ret = DeleteEnhMetaFile(hMetafile);
     ok(ret, "DeleteEnhMetaFile error %d\n", GetLastError());
 
+    /* test ExtTextOut with count == -1 doesn't get written */
+    hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
+    ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
+
+    ret = ExtTextOutA(hdcMetafile, 11, 22, ETO_OPAQUE, &rect, "Test", -1, dx);
+    ok(!ret, "ExtTextOut error %d\n", GetLastError());
+
+    hMetafile = CloseEnhMetaFile(hdcMetafile);
+    ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
+
+    if (compare_emf_bits(hMetafile, EMF_EMPTY_BITS, sizeof(EMF_EMPTY_BITS),
+        "emf_TextOut_negative_count", FALSE) != 0)
+    {
+        dump_emf_bits(hMetafile, "emf_TextOut_negative_count");
+        dump_emf_records(hMetafile, "emf_TextOut_negative_count");
+    }
+
+    ret = DeleteEnhMetaFile(hMetafile);
+    ok(ret, "DeleteEnhMetaFile error %d\n", GetLastError());
+
     ret = ReleaseDC(hwnd, hdcDisplay);
     ok(ret, "ReleaseDC error %d\n", GetLastError());
     DestroyWindow(hwnd);
-- 
2.23.0




More information about the wine-devel mailing list