[colobot] 40/100: Fix crash on class redefinition, closes #703 (#890)
Didier Raboud
odyx at moszumanska.debian.org
Thu Jun 1 18:10:17 UTC 2017
This is an automated email from the git hooks/post-receive script.
odyx pushed a commit to branch debian/master
in repository colobot.
commit d7fae300b9639acd3ae33e1756aaa34d290e1b1b
Author: piotrwalkusz1 <piotrwalkusz1 at users.noreply.github.com>
Date: Sun Jan 15 20:28:52 2017 +0100
Fix crash on class redefinition, closes #703 (#890)
---
src/CBot/CBotClass.cpp | 6 +++---
src/CBot/CBotProgram.cpp | 10 ++++++++++
src/CBot/CBotProgram.h | 6 ++++++
test/unit/CBot/CBot_test.cpp | 24 ++++++++++++++++++++++--
4 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/src/CBot/CBotClass.cpp b/src/CBot/CBotClass.cpp
index 579dda0..13fb837 100644
--- a/src/CBot/CBotClass.cpp
+++ b/src/CBot/CBotClass.cpp
@@ -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);
diff --git a/src/CBot/CBotProgram.cpp b/src/CBot/CBotProgram.cpp
index dce6219..32813de 100644
--- a/src/CBot/CBotProgram.cpp
+++ b/src/CBot/CBotProgram.cpp
@@ -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 )
{
diff --git a/src/CBot/CBotProgram.h b/src/CBot/CBotProgram.h
index d90fb0e..4a64b56 100644
--- a/src/CBot/CBotProgram.h
+++ b/src/CBot/CBotProgram.h
@@ -334,6 +334,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
*/
static CBotExternalCallList* GetExternalCalls();
diff --git a/test/unit/CBot/CBot_test.cpp b/test/unit/CBot/CBot_test.cpp
index 0dae25e..6cf2841 100644
--- a/test/unit/CBot/CBot_test.cpp
+++ b/test/unit/CBot/CBot_test.cpp
@@ -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)
{
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git
More information about the Pkg-games-commits
mailing list