From bbcf98209c9a9810c50d9d83dd53a967f9298b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Mon, 19 Feb 2007 15:24:48 +0100 Subject: [PATCH] wined3d: No bounds checking is done on sampler / texture numbers. --- dlls/d3d8/tests/device.c | 59 ++++++++++++++++++++++++++++++++++++ dlls/d3d9/tests/device.c | 64 ++++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/d3d.c | 30 +++++++++++++++++++ dlls/wined3d/device.c | 24 --------------- 4 files changed, 153 insertions(+), 24 deletions(-) diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 76a6b8b54ae..c4f65d6cc2d 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -942,6 +942,64 @@ cleanup: if(hwnd) DestroyWindow(hwnd); } +static void test_limits(void) +{ + HRESULT hr; + HWND hwnd = NULL; + IDirect3D8 *pD3d = NULL; + IDirect3DDevice8 *pDevice = NULL; + D3DPRESENT_PARAMETERS d3dpp; + D3DDISPLAYMODE d3ddm; + IDirect3DTexture8 *pTexture = NULL; + int i; + + pD3d = pDirect3DCreate8( D3D_SDK_VERSION ); + ok(pD3d != NULL, "Failed to create IDirect3D8 object\n"); + hwnd = CreateWindow( "static", "d3d8_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL ); + ok(hwnd != NULL, "Failed to create window\n"); + if (!pD3d || !hwnd) goto cleanup; + + IDirect3D8_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm ); + ZeroMemory( &d3dpp, sizeof(d3dpp) ); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferWidth = 800; + d3dpp.BackBufferHeight = 600; + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.EnableAutoDepthStencil = TRUE; + d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + + hr = IDirect3D8_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice ); + ok(hr == D3D_OK, "IDirect3D8_CreateDevice failed with %s\n", DXGetErrorString8(hr)); + if(!pDevice) goto cleanup; + + hr = IDirect3DDevice8_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture); + ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed with %s\n", DXGetErrorString8(hr)); + if(!pTexture) goto cleanup; + + /* There are 8 texture stages. We should be able to access all of them */ + for(i = 0; i < 8; i++) { + hr = IDirect3DDevice8_SetTexture(pDevice, i, (IDirect3DBaseTexture8 *) pTexture); + ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString8(hr)); + hr = IDirect3DDevice8_SetTexture(pDevice, i, NULL); + ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString8(hr)); + hr = IDirect3DDevice8_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD); + ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %s\n", i, DXGetErrorString8(hr)); + } + + /* Investigations show that accessing higher textures stage states does not return an error either. Writing + * to too high texture stages(approximately texture 40) causes memory corruption in windows, so there is no + * bounds checking but how do I test that? + */ + +cleanup: + if(pTexture) IDirect3DTexture8_Release(pTexture); + if(pD3d) IDirect3D8_Release(pD3d); + if(pDevice) IDirect3D8_Release(pDevice); + if(hwnd) DestroyWindow(hwnd); +} + START_TEST(device) { HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" ); @@ -964,5 +1022,6 @@ START_TEST(device) test_states(); test_scene(); test_shader(); + test_limits(); } } diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 2e923b8b447..19862db144b 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -1094,6 +1094,69 @@ cleanup: if(hwnd) DestroyWindow(hwnd); } +static void test_limits(void) +{ + HRESULT hr; + HWND hwnd = NULL; + IDirect3D9 *pD3d = NULL; + IDirect3DDevice9 *pDevice = NULL; + D3DPRESENT_PARAMETERS d3dpp; + D3DDISPLAYMODE d3ddm; + IDirect3DTexture9 *pTexture = NULL; + int i; + + pD3d = pDirect3DCreate9( D3D_SDK_VERSION ); + ok(pD3d != NULL, "Failed to create IDirect3D9 object\n"); + hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL ); + ok(hwnd != NULL, "Failed to create window\n"); + if (!pD3d || !hwnd) goto cleanup; + + IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm ); + ZeroMemory( &d3dpp, sizeof(d3dpp) ); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferWidth = 800; + d3dpp.BackBufferHeight = 600; + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.EnableAutoDepthStencil = TRUE; + d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + + hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice ); + ok(hr == D3D_OK, "IDirect3D9_CreateDevice failed with %s\n", DXGetErrorString9(hr)); + if(!pDevice) goto cleanup; + + hr = IDirect3DDevice9_CreateTexture(pDevice, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr)); + if(!pTexture) goto cleanup; + + /* There are 16 pixel samplers. We should be able to access all of them */ + for(i = 0; i < 16; i++) { + hr = IDirect3DDevice9_SetTexture(pDevice, i, (IDirect3DBaseTexture9 *) pTexture); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString9(hr)); + hr = IDirect3DDevice9_SetTexture(pDevice, i, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture for sampler %d failed with %s\n", i, DXGetErrorString9(hr)); + hr = IDirect3DDevice9_SetSamplerState(pDevice, i, D3DSAMP_SRGBTEXTURE, TRUE); + ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState for sampler %d failed with %s\n", i, DXGetErrorString9(hr)); + } + + /* Now test all 8 textures stage states */ + for(i = 0; i < 8; i++) { + hr = IDirect3DDevice9_SetTextureStageState(pDevice, i, D3DTSS_COLOROP, D3DTOP_ADD); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState for texture %d failed with %s\n", i, DXGetErrorString9(hr)); + } + + /* Investigations show that accessing higher samplers / textures stage states does not return an error either. Writing + * to too high samplers(approximately sampler 40) causes memory corruption in windows, so there is no bounds checking + * but how do I test that? + */ +cleanup: + if(pTexture) IDirect3DTexture9_Release(pTexture); + if(pD3d) IDirect3D9_Release(pD3d); + if(pDevice) IDirect3D9_Release(pDevice); + if(hwnd) DestroyWindow(hwnd); +} + START_TEST(device) { HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" ); @@ -1114,5 +1177,6 @@ START_TEST(device) test_cursor(); test_reset(); test_scene(); + test_limits(); } } diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c index 29d0b0cd555..bb37f084bc8 100644 --- a/dlls/ddraw/tests/d3d.c +++ b/dlls/ddraw/tests/d3d.c @@ -521,6 +521,35 @@ static void SceneTest(void) /* TODO: Verify that blitting works in the same way as in d3d9 */ } +static void LimitTest(void) +{ + IDirectDrawSurface7 *pTexture = NULL; + HRESULT hr; + int i; + DDSURFACEDESC2 ddsd; + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + ddsd.dwWidth = 16; + ddsd.dwHeight = 16; + hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &pTexture, NULL); + ok(hr==DD_OK,"CreateSurface returned: %x\n",hr); + if(!pTexture) return; + + for(i = 0; i < 8; i++) { + hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, pTexture); + ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr); + hr = IDirect3DDevice7_SetTexture(lpD3DDevice, i, NULL); + ok(hr == D3D_OK, "IDirect3DDevice8_SetTexture for sampler %d failed with %08x\n", i, hr); + hr = IDirect3DDevice7_SetTextureStageState(lpD3DDevice, i, D3DTSS_COLOROP, D3DTOP_ADD); + ok(hr == D3D_OK, "IDirect3DDevice8_SetTextureStageState for texture %d failed with %08x\n", i, hr); + } + + IDirectDrawSurface7_Release(pTexture); +} + START_TEST(d3d) { init_function_pointers(); @@ -537,5 +566,6 @@ START_TEST(d3d) ProcessVerticesTest(); StateTest(); SceneTest(); + LimitTest(); ReleaseDirect3D(); } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 333e79b31e6..9bd248f43ff 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2695,12 +2695,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface, * GL_MAX_TEXTURE_COORDS_ARB. * Ok GForce say it's ok to use glTexParameter/glGetTexParameter(...). ******************/ - /** NOTE: States are applied in IWineD3DBaseTextre ApplyStateChanges the sampler state handler**/ - if(Sampler > GL_LIMITS(sampler_stages) || Sampler < 0 || Type > WINED3D_HIGHEST_SAMPLER_STATE || Type < 0) { - FIXME("sampler %d type %s(%u) is out of range [max_samplers=%d, highest_state=%d]\n", - Sampler, debug_d3dsamplerstate(Type), Type, GL_LIMITS(sampler_stages), WINED3D_HIGHEST_SAMPLER_STATE); - return WINED3DERR_INVALIDCALL; - } TRACE("(%p) : Sampler=%d, Type=%s(%d), Value=%d\n", This, Sampler, debug_d3dsamplerstate(Type), Type, Value); @@ -2726,7 +2720,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface, static HRESULT WINAPI IWineD3DDeviceImpl_GetSamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type, DWORD* Value) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - /** TODO: check that sampler is in range **/ *Value = This->stateBlock->samplerState[Sampler][Type]; TRACE("(%p) : Sampler %d Type %u Returning %d\n", This, Sampler, Type, *Value); @@ -3685,12 +3678,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *if TRACE("(%p) : Stage=%d, Type=%s(%d), Value=%d\n", This, Stage, debug_d3dtexturestate(Type), Type, Value); - /* Reject invalid texture units */ - if (Stage >= GL_LIMITS(texture_stages)) { - TRACE("Attempt to access invalid texture rejected\n"); - return WINED3DERR_INVALIDCALL; - } - This->updateStateBlock->changed.textureState[Stage][Type] = TRUE; This->updateStateBlock->set.textureState[Stage][Type] = TRUE; This->updateStateBlock->textureState[Stage][Type] = Value; @@ -3789,12 +3776,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface, DWORD } #endif - /* Reject invalid texture units */ - if (Stage >= GL_LIMITS(sampler_stages) || Stage < 0) { - WARN("Attempt to access invalid texture rejected\n"); - return WINED3DERR_INVALIDCALL; - } - if(pTexture != NULL) { /* SetTexture isn't allowed on textures in WINED3DPOOL_SCRATCH; */ @@ -3888,11 +3869,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetTexture(IWineD3DDevice *iface, DWORD IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; TRACE("(%p) : (%d /* Stage */,%p /* ppTexture */)\n", This, Stage, ppTexture); - /* Reject invalid texture units */ - if (Stage >= GL_LIMITS(sampler_stages)) { - TRACE("Attempt to access invalid texture rejected\n"); - return WINED3DERR_INVALIDCALL; - } *ppTexture=This->stateBlock->textures[Stage]; if (*ppTexture) IWineD3DBaseTexture_AddRef(*ppTexture);