Skip to content

Commit 73fb4d4

Browse files
committed
(Heap) safety fixes for CRenderItem.EffectParameters.cpp
1 parent 8cbbd4c commit 73fb4d4

File tree

1 file changed

+139
-16
lines changed

1 file changed

+139
-16
lines changed

Client/core/Graphics/CRenderItem.EffectParameters.cpp

Lines changed: 139 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
#include "StdInc.h"
1111
#include "CRenderItem.EffectParameters.h"
1212

13+
#include <cctype>
14+
#include <cstdlib>
15+
#include <limits>
16+
1317
IMPLEMENT_ENUM_BEGIN(EStateGroup)
1418
ADD_ENUM(STATE_GROUP_RENDER, "renderState")
1519
ADD_ENUM(STATE_GROUP_STAGE, "stageState")
@@ -361,6 +365,9 @@ const SRegisterInfo BigRegisterInfoList[] = {
361365
////////////////////////////////////////////////////////////////
362366
HRESULT CEffectParameters::Begin(UINT* pPasses, DWORD Flags, bool bWorldRender)
363367
{
368+
if (!m_pD3DEffect)
369+
return D3DERR_INVALIDCALL;
370+
364371
if (m_bUsesDepthBuffer && !bWorldRender)
365372
{
366373
// Ensure readable depth buffer is ready to be read
@@ -389,17 +396,20 @@ HRESULT CEffectParameters::Begin(UINT* pPasses, DWORD Flags, bool bWorldRender)
389396
D3DXHANDLE hTexture = m_SecondaryRenderTargetList[i];
390397
IDirect3DBaseTexture9* pD3DTexture = nullptr;
391398
HRESULT hr = m_pD3DEffect->GetTexture(hTexture, &pD3DTexture);
392-
if (hr == D3D_OK && pD3DTexture && pD3DTexture->GetType() == D3DRTYPE_TEXTURE)
399+
if (SUCCEEDED(hr) && pD3DTexture)
393400
{
394-
IDirect3DSurface9* pD3DSurface = nullptr;
395-
HRESULT hrSurface = ((IDirect3DTexture9*)pD3DTexture)->GetSurfaceLevel(0, &pD3DSurface);
396-
if (hrSurface == D3D_OK && pD3DSurface)
401+
if (pD3DTexture->GetType() == D3DRTYPE_TEXTURE)
397402
{
398-
pDevice->SetRenderTarget(i + 1, pD3DSurface);
399-
SAFE_RELEASE(pD3DSurface);
403+
IDirect3DSurface9* pD3DSurface = nullptr;
404+
HRESULT hrSurface = ((IDirect3DTexture9*)pD3DTexture)->GetSurfaceLevel(0, &pD3DSurface);
405+
if (hrSurface == D3D_OK && pD3DSurface)
406+
{
407+
pDevice->SetRenderTarget(i + 1, pD3DSurface);
408+
SAFE_RELEASE(pD3DSurface);
409+
}
400410
}
401-
SAFE_RELEASE(pD3DTexture);
402411
}
412+
SAFE_RELEASE(pD3DTexture);
403413
}
404414
}
405415

@@ -462,8 +472,14 @@ bool CEffectParameters::ApplyCommonHandles()
462472
if (!m_bUsesCommonHandles)
463473
return false;
464474

465-
LPDIRECT3DDEVICE9 pDevice;
466-
m_pD3DEffect->GetDevice(&pDevice);
475+
if (!m_pD3DEffect)
476+
return false;
477+
478+
assert(g_pDeviceState);
479+
480+
LPDIRECT3DDEVICE9 pDevice = nullptr;
481+
if (FAILED(m_pD3DEffect->GetDevice(&pDevice)) || !pDevice)
482+
return false;
467483

468484
D3DXMATRIX matWorld, matView, matProjection;
469485
pDevice->GetTransform(D3DTS_WORLD, &matWorld);
@@ -609,6 +625,7 @@ bool CEffectParameters::ApplyCommonHandles()
609625
if (m_CommonHandles.hProjectionMainScene)
610626
m_pD3DEffect->SetMatrix(m_CommonHandles.hProjectionMainScene, (D3DXMATRIX*)&g_pDeviceState->MainSceneState.TransformState.PROJECTION);
611627

628+
SAFE_RELEASE(pDevice);
612629
return true;
613630
};
614631

@@ -620,6 +637,35 @@ void BOUNDS_CHECK(const void* ptr, int ptrsize, const void* bufstart, int bufsiz
620637
assert((uchar*)ptr + ptrsize <= (uchar*)bufstart + bufsize);
621638
}
622639

640+
static SString TrimAsciiWhitespace(const SString& value)
641+
{
642+
size_t start = 0;
643+
size_t end = value.length();
644+
645+
while (start < end && std::isspace(static_cast<unsigned char>(value[start])))
646+
++start;
647+
648+
while (end > start && std::isspace(static_cast<unsigned char>(value[end - 1])))
649+
--end;
650+
651+
return value.substr(start, end - start);
652+
}
653+
654+
static bool DoesStateGroupUseStageIndex(EStateGroup stateGroup)
655+
{
656+
switch (stateGroup)
657+
{
658+
case STATE_GROUP_STAGE:
659+
case STATE_GROUP_SAMPLER:
660+
case STATE_GROUP_TEXTURE:
661+
case STATE_GROUP_LIGHT:
662+
case STATE_GROUP_LIGHT_ENABLE:
663+
return true;
664+
default:
665+
return false;
666+
}
667+
}
668+
623669
////////////////////////////////////////////////////////////////
624670
//
625671
// CEffectParameters::ApplyMappedHandles
@@ -633,6 +679,11 @@ bool CEffectParameters::ApplyMappedHandles()
633679
if (!m_bUsesMappedHandles)
634680
return false;
635681

682+
if (!m_pD3DEffect)
683+
return false;
684+
685+
assert(g_pDeviceState);
686+
636687
//////////////////////////////////////////
637688
//
638689
// RenderState
@@ -888,6 +939,9 @@ const std::set<D3DXHANDLE>& CEffectParameters::GetModifiedParameters()
888939
////////////////////////////////////////////////////////////////
889940
void CEffectParameters::RestoreParametersDefaultValue(const std::vector<D3DXHANDLE>& parameterList)
890941
{
942+
if (!m_pD3DEffect)
943+
return;
944+
891945
for (auto hParameter : parameterList)
892946
{
893947
std::vector<char>* pBuffer = MapFind(m_defaultValues, hParameter);
@@ -906,6 +960,9 @@ void CEffectParameters::RestoreParametersDefaultValue(const std::vector<D3DXHAND
906960
////////////////////////////////////////////////////////////////
907961
void CEffectParameters::ReadParameterHandles()
908962
{
963+
if (!m_pD3DEffect)
964+
return;
965+
909966
D3DXEFFECT_DESC EffectDesc;
910967
m_pD3DEffect->GetDesc(&EffectDesc);
911968

@@ -957,12 +1014,21 @@ void CEffectParameters::ReadParameterHandles()
9571014
////////////////////////////////////////////////////////////////
9581015
SString CEffectParameters::GetAnnotationNameAndValue(D3DXHANDLE hParameter, uint uiIndex, SString& strOutValue)
9591016
{
1017+
if (!m_pD3DEffect)
1018+
return "";
1019+
9601020
D3DXHANDLE hAnnotation = m_pD3DEffect->GetAnnotation(hParameter, uiIndex);
1021+
if (!hAnnotation)
1022+
return "";
1023+
9611024
D3DXPARAMETER_DESC AnnotDesc;
962-
m_pD3DEffect->GetParameterDesc(hAnnotation, &AnnotDesc);
963-
LPCSTR szAnnotValue;
964-
if (SUCCEEDED(m_pD3DEffect->GetString(hAnnotation, &szAnnotValue)))
1025+
if (FAILED(m_pD3DEffect->GetParameterDesc(hAnnotation, &AnnotDesc)) || !AnnotDesc.Name)
1026+
return "";
1027+
1028+
LPCSTR szAnnotValue = nullptr;
1029+
if (SUCCEEDED(m_pD3DEffect->GetString(hAnnotation, &szAnnotValue)) && szAnnotValue)
9651030
strOutValue = szAnnotValue;
1031+
9661032
return AnnotDesc.Name;
9671033
}
9681034

@@ -975,6 +1041,9 @@ SString CEffectParameters::GetAnnotationNameAndValue(D3DXHANDLE hParameter, uint
9751041
////////////////////////////////////////////////////////////////
9761042
bool CEffectParameters::TryParseSpecialParameter(D3DXHANDLE hParameter, const D3DXPARAMETER_DESC& ParameterDesc)
9771043
{
1044+
if (!m_pD3DEffect)
1045+
return false;
1046+
9781047
// Use semantic if it exists
9791048
SString strName = ParameterDesc.Semantic ? ParameterDesc.Semantic : ParameterDesc.Name;
9801049
if (strName.CompareI("CUSTOMFLAGS"))
@@ -1029,6 +1098,9 @@ bool CEffectParameters::IsSecondaryRenderTarget(D3DXHANDLE hParameter, const D3D
10291098
////////////////////////////////////////////////////////////////
10301099
bool CEffectParameters::AddStandardParameter(D3DXHANDLE hParameter, const D3DXPARAMETER_DESC& ParameterDesc)
10311100
{
1101+
if (!m_pD3DEffect)
1102+
return false;
1103+
10321104
// Use semantic if it exists
10331105
SString strName = ParameterDesc.Semantic ? ParameterDesc.Semantic : ParameterDesc.Name;
10341106
// Add to correct lookup map
@@ -1053,8 +1125,10 @@ bool CEffectParameters::AddStandardParameter(D3DXHANDLE hParameter, const D3DXPA
10531125
{
10541126
std::vector<char> buffer;
10551127
buffer.resize(ParameterDesc.Bytes);
1056-
m_pD3DEffect->GetValue(hParameter, buffer.data(), buffer.size());
1057-
MapSet(m_defaultValues, hParameter, buffer);
1128+
if (SUCCEEDED(m_pD3DEffect->GetValue(hParameter, buffer.data(), buffer.size())))
1129+
{
1130+
MapSet(m_defaultValues, hParameter, buffer);
1131+
}
10581132
}
10591133
return true;
10601134
}
@@ -1082,8 +1156,57 @@ bool CEffectParameters::TryMappingParameterToRegister(D3DXHANDLE hParameter, con
10821156
}
10831157

10841158
// Extract prepended stage number, if any
1085-
int iStage = atoi(strAnnotValue);
1086-
SString strName = strAnnotValue.SplitRight(",", NULL, -1);
1159+
SString strStagePart;
1160+
SString strName;
1161+
const bool bHasStagePart = strAnnotValue.Split(",", &strStagePart, &strName, -1);
1162+
if (!bHasStagePart)
1163+
strName = strAnnotValue;
1164+
1165+
strName = TrimAsciiWhitespace(strName);
1166+
strStagePart = TrimAsciiWhitespace(strStagePart);
1167+
1168+
if (strName.empty())
1169+
continue;
1170+
1171+
int iStage = 0;
1172+
const bool bGroupUsesStage = DoesStateGroupUseStageIndex(stateGroup);
1173+
if (bHasStagePart)
1174+
{
1175+
if (!bGroupUsesStage)
1176+
{
1177+
// Stage index supplied where it is not expected
1178+
continue;
1179+
}
1180+
1181+
if (strStagePart.empty())
1182+
continue;
1183+
1184+
char* pParseEnd = nullptr;
1185+
const long parsedStage = strtol(strStagePart.c_str(), &pParseEnd, 10);
1186+
if (!pParseEnd || *pParseEnd != '\0')
1187+
continue;
1188+
1189+
if (parsedStage < 0 || parsedStage > std::numeric_limits<int>::max())
1190+
continue;
1191+
1192+
iStage = static_cast<int>(parsedStage);
1193+
}
1194+
else if (!bGroupUsesStage)
1195+
{
1196+
iStage = 0;
1197+
}
1198+
1199+
if (bGroupUsesStage)
1200+
{
1201+
const int kMaxFixedStageCount = 8;
1202+
if (iStage < 0 || iStage >= kMaxFixedStageCount)
1203+
continue;
1204+
}
1205+
else if (bHasStagePart)
1206+
{
1207+
// Already handled above, but keep guard for readability
1208+
continue;
1209+
}
10871210

10881211
// Find D3D register line for this group+name
10891212
const SRegisterInfo* pRegsiterInfo = GetRegisterInfo(stateGroup, strName);

0 commit comments

Comments
 (0)