Fix crash on class redefinition, closes #703 (#890)

dev-buzzingcars
piotrwalkusz1 2017-01-15 20:28:52 +01:00 committed by krzys_h
parent 8a0c7279dc
commit d7fae300b9
4 changed files with 41 additions and 5 deletions

View File

@ -455,7 +455,8 @@ CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
std::string name = p->GetString();
CBotClass* pOld = CBotClass::Find(name);
if ( pOld != nullptr && pOld->m_IsDef )
if ( (pOld != nullptr && pOld->m_IsDef) || /* public class exists in different program */
pStack->GetProgram()->ClassExists(name)) /* class exists in this program */
{
pStack->SetError( CBotErrRedefClass, p );
return nullptr;
@ -489,14 +490,13 @@ CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
}
int level = 1;
do // skip over the definition
while (level > 0 && p != nullptr)
{
int type = p->GetType();
p = p->GetNext();
if (type == ID_OPBLK) level++;
if (type == ID_CLBLK) level--;
}
while (level > 0 && p != nullptr);
if (level > 0) pStack->SetError(CBotErrCloseBlock, classe->m_pOpenblk);

View File

@ -281,6 +281,16 @@ const std::list<CBotFunction*>& CBotProgram::GetFunctions()
return m_functions;
}
bool CBotProgram::ClassExists(std::string name)
{
for (CBotClass* p : m_classes)
{
if ( p->GetName() == name ) return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
CBotTypResult cSizeOf( CBotVar* &pVar, void* pUser )
{

View File

@ -333,6 +333,12 @@ public:
*/
const std::list<CBotFunction*>& GetFunctions();
/**
* \brief Check if class with that name was created in this program
* \return True if class was defined in this program, otherwise, false
*/
bool ClassExists(std::string name);
/**
* \brief Returns static list of all registered external calls
*/

View File

@ -932,8 +932,19 @@ TEST_F(CBotUT, ClassMethodRedefined)
);
}
// TODO: Not only doesn't work but segfaults
TEST_F(CBotUT, DISABLED_ClassRedefined)
TEST_F(CBotUT, ClassRedefinedInDifferentPrograms)
{
auto publicProgram = ExecuteTest(
"public class TestClass {}\n"
);
ExecuteTest(
"public class TestClass {}\n",
CBotErrRedefClass
);
}
TEST_F(CBotUT, ClassRedefinedInOneProgram)
{
ExecuteTest(
"public class TestClass {}\n"
@ -942,6 +953,15 @@ TEST_F(CBotUT, DISABLED_ClassRedefined)
);
}
TEST_F(CBotUT, ClassMissingCloseBlock)
{
ExecuteTest(
"public class Something\n"
"{\n",
CBotErrCloseBlock
);
}
// TODO: NOOOOOO!!! Nononononono :/
TEST_F(CBotUT, DISABLED_PublicClasses)
{