Skip to content

Commit 13e58bd

Browse files
committed
Fix stack overflow when tasks are called in a loop.
1 parent ce74d74 commit 13e58bd

22 files changed

+199
-124
lines changed

copasi/core/CObjectInterface.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019 by Pedro Mendes, Rector and Visitors of the
1+
// Copyright (C) 2019 - 2022 by Pedro Mendes, Rector and Visitors of the
22
// University of Virginia, University of Heidelberg, and University
33
// of Connecticut School of Medicine.
44
// All rights reserved.
@@ -90,7 +90,7 @@ CObjectInterface * CObjectInterface::GetObjectFromCN(const CObjectInterface::Con
9090
if (pos + ContainerName.length() == objName.length())
9191
pObject = *it;
9292
else
93-
pObject = (*it)->getObject(objName.substr(pos + ContainerName.length() + 1));
93+
pObject = (*it)->getObject(CCommonName(objName.substr(pos)).getRemainder());
9494
}
9595

9696
// if not found check the data model if we have one and have not yet done so

copasi/lna/CLNAProblem.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019 by Pedro Mendes, Rector and Visitors of the
1+
// Copyright (C) 2019 - 2022 by Pedro Mendes, Rector and Visitors of the
22
// University of Virginia, University of Heidelberg, and University
33
// of Connecticut School of Medicine.
44
// All rights reserved.
@@ -103,10 +103,10 @@ void CLNAProblem::setSteadyStateRequested(const bool & steadyStateRequested)
103103
bool CLNAProblem::isSteadyStateRequested() const
104104
{return (getValue< std::string >("Steady-State") != "");}
105105

106-
CSteadyStateTask * CLNAProblem::getSubTask() const
106+
CCopasiTask * CLNAProblem::getSubTask() const
107107
{
108108
if (isSteadyStateRequested())
109-
return dynamic_cast<CSteadyStateTask *>(CRootContainer::getKeyFactory()->get(getValue< std::string >("Steady-State")));
109+
return dynamic_cast< CCopasiTask *>(CRootContainer::getKeyFactory()->get(getValue< std::string >("Steady-State")));
110110
else
111111
return NULL;
112112
}

copasi/lna/CLNAProblem.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019 by Pedro Mendes, Rector and Visitors of the
1+
// Copyright (C) 2019 - 2022 by Pedro Mendes, Rector and Visitors of the
22
// University of Virginia, University of Heidelberg, and University
33
// of Connecticut School of Medicine.
44
// All rights reserved.
@@ -69,9 +69,9 @@ class CLNAProblem: public CCopasiProblem
6969

7070
/**
7171
* Retrieve the subtask
72-
* return CSteadyStateTask * pSubTask;
72+
* return CCopasiTask * pSubTask;
7373
*/
74-
CSteadyStateTask * getSubTask() const;
74+
virtual CCopasiTask * getSubTask() const override;
7575

7676
/**
7777
* Load a LNA problem

copasi/lna/CLNATask.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019 - 2020 by Pedro Mendes, Rector and Visitors of the
1+
// Copyright (C) 2019 - 2022 by Pedro Mendes, Rector and Visitors of the
22
// University of Virginia, University of Heidelberg, and University
33
// of Connecticut School of Medicine.
44
// All rights reserved.
@@ -102,7 +102,7 @@ bool CLNATask::initialize(const OutputFlag & of,
102102
//initialize reporting
103103
success &= CCopasiTask::initialize(of, pOutputHandler, pOstream);
104104

105-
CSteadyStateTask *pSubTask = pProblem->getSubTask();
105+
CCopasiTask * pSubTask = pProblem->getSubTask();
106106

107107
if (pSubTask)
108108
success &= pSubTask->initialize(CCopasiTask::NO_OUTPUT, NULL, mReport.getStream());
@@ -120,8 +120,7 @@ bool CLNATask::process(const bool & useInitialValues)
120120
CLNAMethod* pMethod = dynamic_cast<CLNAMethod *>(mpMethod);
121121
assert(pMethod);
122122

123-
CSteadyStateTask *pSubTask =
124-
dynamic_cast<CLNAProblem *>(mpProblem)->getSubTask();
123+
CSteadyStateTask * pSubTask = dynamic_cast< CSteadyStateTask * >(mpProblem->getSubTask());
125124

126125
if (pSubTask)
127126
{
@@ -182,8 +181,7 @@ bool CLNATask::process(const bool & useInitialValues)
182181
// virtual
183182
bool CLNATask::setCallBack(CProcessReport * pCallBack)
184183
{
185-
CSteadyStateTask *pSubTask =
186-
dynamic_cast<CLNAProblem *>(mpProblem)->getSubTask();
184+
CCopasiTask *pSubTask = mpProblem->getSubTask();
187185

188186
if (pSubTask)
189187
{

copasi/optimization/COptProblem.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019 - 2021 by Pedro Mendes, Rector and Visitors of the
1+
// Copyright (C) 2019 - 2022 by Pedro Mendes, Rector and Visitors of the
22
// University of Virginia, University of Heidelberg, and University
33
// of Connecticut School of Medicine.
44
// All rights reserved.
@@ -318,14 +318,7 @@ void COptProblem::initObjects()
318318

319319
bool COptProblem::initializeSubtaskBeforeOutput()
320320
{
321-
// We have a CFitProblem for which it is OK not to have a subtask.
322-
if (mpParmSubTaskCN == NULL)
323-
return true;
324-
325-
CObjectInterface::ContainerList ListOfContainer;
326-
ListOfContainer.push_back(getObjectAncestor("Vector"));
327-
328-
mpSubTaskSrc = dynamic_cast< CCopasiTask * >(CObjectInterface::GetObjectFromCN(ListOfContainer, *mpParmSubTaskCN));
321+
mpSubTaskSrc = getSubTask();
329322

330323
pdelete(mpSubTask);
331324
mpSubTask = CTaskFactory::copy(mpSubTaskSrc, this);
@@ -477,6 +470,19 @@ void COptProblem::updateContainer(const bool & update)
477470
}
478471
}
479472

473+
// virtual
474+
CCopasiTask * COptProblem::getSubTask() const
475+
{
476+
// We have a CFitProblem for which it is OK not to have a subtask.
477+
if (mpParmSubTaskCN == NULL)
478+
return NULL;
479+
480+
CObjectInterface::ContainerList ListOfContainer;
481+
ListOfContainer.push_back(getObjectAncestor("Vector"));
482+
483+
return dynamic_cast< CCopasiTask * >(CObjectInterface::GetObjectFromCN(ListOfContainer, *mpParmSubTaskCN));
484+
}
485+
480486
bool COptProblem::restore(const bool & updateModel)
481487
{
482488
bool success = true;

copasi/optimization/COptProblem.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019 - 2021 by Pedro Mendes, Rector and Visitors of the
1+
// Copyright (C) 2019 - 2022 by Pedro Mendes, Rector and Visitors of the
22
// University of Virginia, University of Heidelberg, and University
33
// of Connecticut School of Medicine.
44
// All rights reserved.
@@ -164,6 +164,13 @@ class COptProblem : public CCopasiProblem
164164
*/
165165
virtual bool restore(const bool & updateModel);
166166

167+
/**
168+
* Retrieve the optional sub task
169+
*
170+
* @return CCopasiTask* * pSubTask
171+
*/
172+
virtual CCopasiTask * getSubTask() const override;
173+
167174
/**
168175
* Check whether all parameters are within their boundaries.
169176
* @result bool within

copasi/optimization/COptTask.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019 - 2021 by Pedro Mendes, Rector and Visitors of the
1+
// Copyright (C) 2019 - 2022 by Pedro Mendes, Rector and Visitors of the
22
// University of Virginia, University of Heidelberg, and University
33
// of Connecticut School of Medicine.
44
// All rights reserved.
@@ -93,7 +93,8 @@ bool COptTask::setCallBack(CProcessReport * pCallBack)
9393
{
9494
bool success = CCopasiTask::setCallBack(pCallBack);
9595

96-
if (mpProblem != NULL)
96+
if (success &&
97+
mpProblem != NULL)
9798
{
9899
success &= mpProblem->setCallBack(pCallBack);
99100
}
@@ -105,6 +106,9 @@ bool COptTask::initialize(const OutputFlag & of,
105106
COutputHandler * pOutputHandler,
106107
std::ostream * pOstream)
107108
{
109+
if (!isTaskValid())
110+
return false;
111+
108112
COptProblem * pProblem = dynamic_cast<COptProblem *>(mpProblem);
109113
COptMethod * pMethod = dynamic_cast<COptMethod *>(mpMethod);
110114

copasi/scan/CScanProblem.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019 - 2021 by Pedro Mendes, Rector and Visitors of the
1+
// Copyright (C) 2019 - 2022 by Pedro Mendes, Rector and Visitors of the
22
// University of Virginia, University of Heidelberg, and University
33
// of Connecticut School of Medicine.
44
// All rights reserved.
@@ -81,6 +81,24 @@ void CScanProblem::initializeParameter()
8181
}
8282

8383
//***********************************
84+
// virtual
85+
CCopasiTask * CScanProblem::getSubTask() const
86+
{
87+
CDataModel* pDataModel = getObjectDataModel();
88+
CTaskEnum::Task SubTaskType = getSubtask();
89+
90+
if (pDataModel != NULL)
91+
{
92+
CDataVectorN< CCopasiTask >::iterator it = pDataModel->getTaskList()->begin();
93+
CDataVectorN< CCopasiTask >::iterator end = pDataModel->getTaskList()->end();
94+
95+
for (; it != end; ++it)
96+
if (it->getType() == SubTaskType)
97+
return &*it;
98+
}
99+
100+
return NULL;
101+
}
84102

85103
void CScanProblem::setSubtask(CTaskEnum::Task type)
86104
{
@@ -120,7 +138,6 @@ void CScanProblem::setContinueOnError(bool coe)
120138
setValue("Continue on Error", coe);
121139
}
122140

123-
124141
//************************************
125142

126143
void CScanProblem::load(CReadConfig & C_UNUSED(configBuffer),
@@ -200,7 +217,6 @@ CCopasiParameterGroup* CScanProblem::createScanItem(CScanProblem::Type type, siz
200217
tmp->addParameter("Use Values", CCopasiParameter::Type::BOOL, false);
201218
}
202219

203-
204220
if (type == SCAN_RANDOM)
205221
{
206222
tmp->addParameter("Distribution type", CCopasiParameter::Type::UINT, (unsigned C_INT32)0);
@@ -222,18 +238,10 @@ void CScanProblem::clearScanItems()
222238

223239
bool CScanProblem::restore(const bool & updateModel)
224240
{
225-
auto * dm = getObjectDataModel();
226-
227-
if (dm == NULL)
228-
return false;
241+
CCopasiTask * pSubTask = getSubTask();
229242

230-
auto& tasks = *dm->getTaskList();
231-
232-
for (auto & task : tasks)
233-
{
234-
if (task.getType() == getSubtask())
235-
return task.restore();
236-
}
243+
if (pSubTask != NULL)
244+
return pSubTask->restore();
237245

238246
return true;
239247
}

copasi/scan/CScanProblem.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019 - 2021 by Pedro Mendes, Rector and Visitors of the
1+
// Copyright (C) 2019 - 2022 by Pedro Mendes, Rector and Visitors of the
22
// University of Virginia, University of Heidelberg, and University
33
// of Connecticut School of Medicine.
44
// All rights reserved.
@@ -76,6 +76,13 @@ class CScanProblem : public CCopasiProblem
7676
*/
7777
~CScanProblem();
7878

79+
/**
80+
* Retrieve the optional sub task
81+
*
82+
* @return CCopasiTask* * pSubTask
83+
*/
84+
virtual CCopasiTask * getSubTask() const override;
85+
7986
/**
8087
* Set the type of the subtask.
8188
*/

copasi/scan/CScanTask.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2019 - 2021 by Pedro Mendes, Rector and Visitors of the
1+
// Copyright (C) 2019 - 2022 by Pedro Mendes, Rector and Visitors of the
22
// University of Virginia, University of Heidelberg, and University
33
// of Connecticut School of Medicine.
44
// All rights reserved.
@@ -88,7 +88,8 @@ bool CScanTask::initialize(const OutputFlag & of,
8888
COutputHandler * pOutputHandler,
8989
std::ostream * pOstream)
9090
{
91-
assert(mpProblem && mpMethod);
91+
if (!isTaskValid())
92+
return false;
9293

9394
bool success = mpMethod->isValidProblem(mpProblem);
9495

0 commit comments

Comments
 (0)