1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Added bounds checking to blits and color fills

This commit is contained in:
narzoul 2019-08-24 21:23:27 +02:00
parent b8456cc1d4
commit 77bdff3f1c
2 changed files with 42 additions and 7 deletions

View File

@ -190,12 +190,24 @@ namespace D3dDdi
HRESULT Resource::blt(D3DDDIARG_BLT data)
{
auto srcResource = m_device.getResource(data.hSrcResource);
if (srcResource &&
D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool &&
D3DDDIPOOL_SYSTEMMEM == srcResource->m_fixedData.Pool)
if (!isValidRect(data.DstSubResourceIndex, data.DstRect))
{
return m_device.getOrigVtable().pfnBlt(m_device, &data);
return S_OK;
}
auto srcResource = m_device.getResource(data.hSrcResource);
if (srcResource)
{
if (!srcResource->isValidRect(data.SrcSubResourceIndex, data.SrcRect))
{
return S_OK;
}
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool &&
D3DDDIPOOL_SYSTEMMEM == srcResource->m_fixedData.Pool)
{
return m_device.getOrigVtable().pfnBlt(m_device, &data);
}
}
if (isOversized())
@ -257,9 +269,23 @@ namespace D3dDdi
return LOG_RESULT(S_OK);
}
HRESULT Resource::colorFill(const D3DDDIARG_COLORFILL& data)
void Resource::clipRect(UINT subResourceIndex, RECT& rect)
{
rect.left = std::max<LONG>(rect.left, 0);
rect.top = std::max<LONG>(rect.top, 0);
rect.right = std::min<LONG>(rect.right, m_fixedData.pSurfList[subResourceIndex].Width);
rect.bottom = std::min<LONG>(rect.bottom, m_fixedData.pSurfList[subResourceIndex].Height);
}
HRESULT Resource::colorFill(D3DDDIARG_COLORFILL data)
{
LOG_FUNC("Resource::colorFill", data);
clipRect(data.SubResourceIndex, data.DstRect);
if (data.DstRect.left >= data.DstRect.right || data.DstRect.top >= data.DstRect.bottom)
{
return S_OK;
}
if (m_lockResource)
{
auto& lockData = m_lockData[data.SubResourceIndex];
@ -464,6 +490,13 @@ namespace D3dDdi
return m_fixedData.SurfCount != m_origData.SurfCount;
}
bool Resource::isValidRect(UINT subResourceIndex, const RECT& rect)
{
return rect.left >= 0 && rect.top >= 0 && rect.left < rect.right && rect.top < rect.bottom &&
rect.right <= static_cast<LONG>(m_fixedData.pSurfList[subResourceIndex].Width) &&
rect.bottom <= static_cast<LONG>(m_fixedData.pSurfList[subResourceIndex].Height);
}
HRESULT Resource::lock(D3DDDIARG_LOCK& data)
{
if (isOversized())

View File

@ -27,7 +27,7 @@ namespace D3dDdi
operator HANDLE() const { return m_handle; }
HRESULT blt(D3DDDIARG_BLT data);
HRESULT colorFill(const D3DDDIARG_COLORFILL& data);
HRESULT colorFill(D3DDDIARG_COLORFILL data);
void fixVertexData(UINT offset, UINT count, UINT stride);
void* getLockPtr(UINT subResourceIndex);
HRESULT lock(D3DDDIARG_LOCK& data);
@ -77,6 +77,7 @@ namespace D3dDdi
HRESULT bltLock(D3DDDIARG_LOCK& data);
HRESULT bltUnlock(const D3DDDIARG_UNLOCK& data);
void clipRect(UINT subResourceIndex, RECT& rect);
HRESULT copySubResource(HANDLE dstResource, HANDLE srcResource, UINT subResourceIndex);
void copyToSysMem(UINT subResourceIndex);
void copyToVidMem(UINT subResourceIndex);
@ -84,6 +85,7 @@ namespace D3dDdi
void createLockResource();
void createSysMemResource(const std::vector<D3DDDI_SURFACEINFO>& surfaceInfo);
bool isOversized() const;
bool isValidRect(UINT subResourceIndex, const RECT& rect);
HRESULT presentationBlt(const D3DDDIARG_BLT& data, Resource& srcResource);
HRESULT splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect);