Author: tkreuzer Date: Tue Sep 9 08:19:10 2008 New Revision: 36081
URL: http://svn.reactos.org/svn/reactos?rev=36081&view=rev Log: - Add more parameter checks to NtGdiExtCreateRegion. Fixes a crash in gdi32_winetest clipping (12 failures left) and FF 3.1 - Do not copy more data than allocated for the region - Add coordinate transformation See issue #3724 for more details.
Modified: trunk/reactos/subsystems/win32/win32k/objects/region.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/region.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/region.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/region.c [iso-8859-1] Tue Sep 9 08:19:10 2008 @@ -2499,18 +2499,16 @@ PROSRGNDATA Region; DWORD nCount = 0; NTSTATUS Status = STATUS_SUCCESS; - - if (Count < FIELD_OFFSET(RGNDATA, Buffer)) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return NULL; - } + MATRIX matrix;
_SEH_TRY { ProbeForRead(RgnData, Count, 1); nCount = RgnData->rdh.nCount; - if ((Count - FIELD_OFFSET(RGNDATA, Buffer)) / sizeof(RECT) < nCount) + if (Count < sizeof(RGNDATAHEADER) + nCount * sizeof(RECT) || + nCount == 0 || + RgnData->rdh.iType != RDH_RECTANGLES || + RgnData->rdh.dwSize != sizeof(RGNDATAHEADER)) { Status = STATUS_INVALID_PARAMETER; _SEH_LEAVE; @@ -2538,12 +2536,38 @@
_SEH_TRY { - RtlCopyMemory(&Region->rdh, - RgnData, - FIELD_OFFSET(RGNDATA, Buffer)); - RtlCopyMemory(Region->Buffer, - RgnData->Buffer, - Count - FIELD_OFFSET(RGNDATA, Buffer)); + /* Copy header */ + Region->rdh = RgnData->rdh; + + if (Xform) + { + ULONG ret; + + /* Init the XFORMOBJ from the Xform struct */ + Status = STATUS_INVALID_PARAMETER; + ret = XFORMOBJ_iSetXform((XFORMOBJ*)&matrix, (XFORML*)Xform); + + /* Check for error, also no scale and shear allowed */ + if (ret != DDI_ERROR && ret != GX_GENERAL) + { + /* Apply the coordinate transformation on the rects */ + if (XFORMOBJ_bApplyXform((XFORMOBJ*)&matrix, + XF_LTOL, + nCount * 2, + RgnData->Buffer, + Region->Buffer)) + { + Status = STATUS_SUCCESS; + } + } + } + else + { + /* Copy rect coordinates */ + RtlCopyMemory(Region->Buffer, + RgnData->Buffer, + nCount * sizeof(RECT)); + } } _SEH_HANDLE {