Skip to content

Commit 09c94ae

Browse files
authored
Improve IplStoreSA validation to avoid crashes (#4572)
* Improve IplStoreSA validation to avoid crashes
1 parent 94c1d8b commit 09c94ae

File tree

1 file changed

+83
-34
lines changed

1 file changed

+83
-34
lines changed

Client/game_sa/CIplStoreSA.cpp

Lines changed: 83 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,52 @@ CIplStoreSA::CIplStoreSA() : m_isStreamingEnabled(true), m_ppIplPoolInterface((C
2222

2323
void CIplStoreSA::UnloadAndDisableStreaming(int iplId)
2424
{
25+
// Is pool valid?
26+
if (!m_ppIplPoolInterface)
27+
return;
28+
29+
// Is pool object valid?
30+
auto pool = *m_ppIplPoolInterface;
31+
if (!pool)
32+
return;
33+
34+
// Is IPL in pool?
35+
if (!pool->IsContains(iplId))
36+
return;
37+
38+
// Is IPL object valid?
39+
auto ipl = pool->GetObject(iplId);
40+
if (!ipl)
41+
return;
42+
2543
typedef void*(__cdecl * Function_EnableStreaming)(int);
2644
((Function_EnableStreaming)(0x405890))(iplId);
2745
}
2846

2947
void CIplStoreSA::EnableStreaming(int iplId)
3048
{
31-
auto ipl = (*m_ppIplPoolInterface)->GetObject(iplId);
49+
// Is pool valid?
50+
if (!m_ppIplPoolInterface)
51+
return;
52+
53+
// Is pool object valid?
54+
auto pool = *m_ppIplPoolInterface;
55+
if (!pool)
56+
return;
57+
58+
// Is IPL in pool?
59+
if (!pool->IsContains(iplId))
60+
return;
61+
62+
// Is IPL object valid?
63+
auto ipl = pool->GetObject(iplId);
64+
if (!ipl)
65+
return;
66+
3267
ipl->bDisabledStreaming = false;
3368

34-
(*gIplQuadTree)->AddItem(ipl, &ipl->rect);
69+
if (*gIplQuadTree)
70+
(*gIplQuadTree)->AddItem(ipl, &ipl->rect);
3571
}
3672

3773
void CIplStoreSA::SetDynamicIplStreamingEnabled(bool state)
@@ -42,27 +78,33 @@ void CIplStoreSA::SetDynamicIplStreamingEnabled(bool state)
4278
// Ipl with 0 index is generic
4379
// We don't unload this IPL
4480

45-
auto pPool = *m_ppIplPoolInterface;
81+
auto pool = *m_ppIplPoolInterface;
82+
if (!pool)
83+
return;
84+
85+
// Collect all IPL ids
86+
std::vector<int> iplIds;
87+
iplIds.reserve(pool->m_nSize);
88+
89+
for (int i = 1; i < pool->m_nSize; i++)
90+
{
91+
if (pool->IsContains(i))
92+
iplIds.push_back(i);
93+
}
94+
95+
// Now enable/disable streaming for all IPLs
4696
if (!state)
4797
{
48-
for (int i = 1; i < pPool->m_nSize; i++)
49-
{
50-
if (pPool->IsContains(i))
51-
{
52-
UnloadAndDisableStreaming(i);
53-
}
54-
}
55-
(*gIplQuadTree)->RemoveAllItems();
98+
for (int iplId : iplIds)
99+
UnloadAndDisableStreaming(iplId);
100+
101+
if (*gIplQuadTree)
102+
(*gIplQuadTree)->RemoveAllItems();
56103
}
57104
else
58105
{
59-
for (int i = 1; i < pPool->m_nSize; i++)
60-
{
61-
if (pPool->IsContains(i))
62-
{
63-
EnableStreaming(i);
64-
}
65-
}
106+
for (int iplId : iplIds)
107+
EnableStreaming(iplId);
66108
}
67109

68110
m_isStreamingEnabled = state;
@@ -76,27 +118,34 @@ void CIplStoreSA::SetDynamicIplStreamingEnabled(bool state, std::function<bool(C
76118
// Ipl with 0 index is generic
77119
// We don't unload this IPL
78120

79-
auto pPool = *m_ppIplPoolInterface;
121+
auto pool = *m_ppIplPoolInterface;
122+
if (!pool)
123+
return;
124+
125+
// Collect IPL ids that match the filter
126+
std::vector<int> iplIds;
127+
iplIds.reserve(pool->m_nSize);
128+
129+
for (int i = 1; i < pool->m_nSize; i++)
130+
{
131+
auto ipl = pool->GetObject(i);
132+
if (ipl && pool->IsContains(i) && filter(ipl))
133+
iplIds.push_back(i);
134+
}
135+
136+
// Apply the streaming state change
80137
if (!state)
81138
{
82-
for (int i = 1; i < pPool->m_nSize; i++)
83-
{
84-
if (pPool->IsContains(i) && filter(pPool->GetObject(i)))
85-
{
86-
UnloadAndDisableStreaming(i);
87-
}
88-
}
89-
(*gIplQuadTree)->RemoveAllItems();
139+
for (int iplId : iplIds)
140+
UnloadAndDisableStreaming(iplId);
141+
142+
if (*gIplQuadTree)
143+
(*gIplQuadTree)->RemoveAllItems();
90144
}
91145
else
92146
{
93-
for (int i = 1; i < pPool->m_nSize; i++)
94-
{
95-
if (pPool->IsContains(i) && filter(pPool->GetObject(i)))
96-
{
97-
EnableStreaming(i);
98-
}
99-
}
147+
for (int iplId : iplIds)
148+
EnableStreaming(iplId);
100149
}
101150

102151
m_isStreamingEnabled = state;

0 commit comments

Comments
 (0)