From 82c94064179a39582cb43759435e4bda83a18a1d Mon Sep 17 00:00:00 2001 From: ageay Date: Wed, 11 Jul 2012 12:38:21 +0000 Subject: [PATCH] Protection against invalid size in expression evaluation. --- .../ExprEval/InterpKernelExprParser.cxx | 26 +++++++++++++++---- .../ExprEval/InterpKernelExprParser.hxx | 4 +-- src/MEDCoupling/MEDCouplingMemArray.cxx | 6 ++--- .../Test/MEDCouplingBasicsTest3.cxx | 1 + .../Test/MEDCouplingBasicsTest4.cxx | 2 ++ src/MEDCoupling_Swig/MEDCouplingBasicsTest.py | 2 ++ 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx index a8867850c..69dabca7a 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx @@ -92,7 +92,7 @@ void LeafExprVar::fillValue(Value *val) const throw(INTERP_KERNEL::Exception) val->setVarname(_fast_pos,_var_name); } -void LeafExprVar::prepareExprEvaluation(const std::vector& vars) const throw(INTERP_KERNEL::Exception) +void LeafExprVar::prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const throw(INTERP_KERNEL::Exception) { std::vector::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name); if(iter==vars.end()) @@ -103,9 +103,25 @@ void LeafExprVar::prepareExprEvaluation(const std::vector& vars) co std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss,", ")); throw INTERP_KERNEL::Exception(oss.str().c_str()); } - return; + else + { + int relPos=-7-_fast_pos; + if(relPos>=targetNbOfCompo) + { + std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found recognized unitary vector \"" << _var_name << "\" which implies that component #" << relPos; + oss << " exists, but it is not the case component id should be in [0," << targetNbOfCompo << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + return; + } } _fast_pos=(int)std::distance(vars.begin(),iter); + if(_fast_pos>=nbOfCompo) + { + std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found var \"" << _var_name << "\" on place " << _fast_pos << " whereas only must be in [0," << nbOfCompo << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } } void LeafExprVar::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception) @@ -275,17 +291,17 @@ void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *o delete res; } -void ExprParser::prepareExprEvaluation(const std::vector& vars) const throw(INTERP_KERNEL::Exception) +void ExprParser::prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const throw(INTERP_KERNEL::Exception) { if(_leaf) { LeafExprVar *leafC=dynamic_cast(_leaf); if(leafC) - leafC->prepareExprEvaluation(vars); + leafC->prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); } else for(std::list::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).prepareExprEvaluation(vars); + (*iter).prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); } void ExprParser::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception) diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx index 0d01bad10..a87f335a7 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx @@ -67,7 +67,7 @@ namespace INTERP_KERNEL void compileX86_64(std::vector& ass) const; void fillValue(Value *val) const throw(INTERP_KERNEL::Exception); std::string getVar() const { return _var_name; } - void prepareExprEvaluation(const std::vector& vars) const throw(INTERP_KERNEL::Exception); + void prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const throw(INTERP_KERNEL::Exception); void prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception); void replaceValues(const std::vector& valuesInExpr) throw(INTERP_KERNEL::Exception); static bool isRecognizedKeyVar(const std::string& var, int& pos); @@ -88,7 +88,7 @@ namespace INTERP_KERNEL bool isParsingSuccessfull() const { return _is_parsing_ok; } double evaluate() const throw(INTERP_KERNEL::Exception); DecompositionInUnitBase evaluateUnit() const throw(INTERP_KERNEL::Exception); - void prepareExprEvaluation(const std::vector& vars) const throw(INTERP_KERNEL::Exception); + void prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const throw(INTERP_KERNEL::Exception); void evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const throw(INTERP_KERNEL::Exception); void prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception); void getSetOfVars(std::set& vars) const; diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 0eae4e12b..8dae06d62 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -2135,7 +2135,7 @@ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) cons throw INTERP_KERNEL::Exception(oss.str().c_str()); } std::vector varsV(vars.begin(),vars.end()); - expr.prepareExprEvaluation(varsV); + expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp); // DataArrayDouble *newArr=DataArrayDouble::New(); int nbOfTuples=getNumberOfTuples(); @@ -2210,7 +2210,7 @@ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) con std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); throw INTERP_KERNEL::Exception(oss.str().c_str()); } - expr.prepareExprEvaluation(getVarsOnComponent()); + expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp); // DataArrayDouble *newArr=DataArrayDouble::New(); int nbOfTuples=getNumberOfTuples(); @@ -2254,7 +2254,7 @@ DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector(oss," ")); throw INTERP_KERNEL::Exception(oss.str().c_str()); } - expr.prepareExprEvaluation(varsOrder); + expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp); // DataArrayDouble *newArr=DataArrayDouble::New(); int nbOfTuples=getNumberOfTuples(); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx index a9d8b8759..a02421060 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx @@ -1391,6 +1391,7 @@ void MEDCouplingBasicsTest3::testExtrudedMesh5() e->setCoordsAt(0,d); MEDCouplingUMesh *f=e->buildUnstructured(); DataArrayDouble *g=f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); + CPPUNIT_ASSERT_THROW(f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*KVec"),INTERP_KERNEL::Exception); // KVec refers to component #2 and there is only 2 components ! DataArrayDouble *h=g->fromPolarToCart(); f->setCoords(h); MEDCouplingUMesh *i=c->buildExtrudedMesh(f,1); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx index 4c5256e54..c867a699a 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx @@ -378,6 +378,8 @@ void MEDCouplingBasicsTest4::testApplyFuncThree1() for(int i=0;i<5;i++) CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-12); da2->decrRef(); + std::vector vs2(4); vs2[0]="x"; vs2[1]="y"; vs2[2]="z"; vs2[3]="a"; + CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs2,"x+a"),INTERP_KERNEL::Exception); f1->setArray(da); CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 5fa0833a8..79f5adb37 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -5027,6 +5027,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): e.setCoordsAt(0,d); f=e.buildUnstructured(); g=f.getCoords().applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); + self.assertRaises(InterpKernelException,f.getCoords().applyFunc,2,"3.5*IVec+x/6*3.14159265359*KVec"); # KVec refers to component #2 and there is only 2 components ! h=g.fromPolarToCart(); f.setCoords(h); i=c.buildExtrudedMesh(f,1); @@ -6892,6 +6893,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): for i in xrange(5): self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),12); pass + self.assertRaises(InterpKernelException, da.applyFunc3, 1, ["x","y","z","a"],"x+a") f1.setArray(da); self.assertEqual(3,f1.getNumberOfComponents()); self.assertEqual(5,f1.getNumberOfTuples()); -- 2.39.2