From 96bc4e98b56b27856dced632cdb6767afb411179 Mon Sep 17 00:00:00 2001 From: eap Date: Tue, 28 Jan 2014 10:04:39 +0000 Subject: [PATCH] 22464: [CEA 1046] SEGFAULT when reading a SAUV file in V7.3.0 and V7_main +//================================================================================ +/*! + * \brief Safely adds a new Group + */ +//================================================================================ + +Group* IntermediateMED::addNewGroup(std::vector* groupsToFix) --- src/MEDLoader/SauvMedConvertor.cxx | 68 ++++++++++++++++++++++++++++++ src/MEDLoader/SauvMedConvertor.hxx | 2 +- src/MEDLoader/SauvReader.cxx | 9 ++-- 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/MEDLoader/SauvMedConvertor.cxx b/src/MEDLoader/SauvMedConvertor.cxx index ad16d610a..2449c8468 100644 --- a/src/MEDLoader/SauvMedConvertor.cxx +++ b/src/MEDLoader/SauvMedConvertor.cxx @@ -2302,6 +2302,74 @@ void IntermediateMED::checkDataAvailability() const THROW_IK_EXCEPTION("Nodes and coordinates mismatch"); } +//================================================================================ +/*! + * \brief Safely adds a new Group + */ +//================================================================================ + +Group* IntermediateMED::addNewGroup(std::vector* groupsToFix) +{ + if ( _groups.size() == _groups.capacity() ) // re-allocation would occure + { + std::vector newGroups( _groups.size() ); + newGroups.push_back( Group() ); + + for ( size_t i = 0; i < _groups.size(); ++i ) + { + // avoid copying _cells + std::vector cells; + cells.swap( _groups[i]._cells ); + newGroups[i] = _groups[i]; + newGroups[i]._cells.swap( cells ); + + // correct pointers to sub-groups + for ( size_t j = 0; j < _groups[i]._groups.size(); ++j ) + { + int iG = _groups[i]._groups[j] - &_groups[0]; + newGroups[i]._groups[j] = & newGroups[ iG ]; + } + } + + // fix given groups + if ( groupsToFix ) + for ( size_t i = 0; i < groupsToFix->size(); ++i ) + if ( (*groupsToFix)[i] ) + { + int iG = (*groupsToFix)[i] - &_groups[0]; + (*groupsToFix)[i] = & newGroups[ iG ]; + } + + // fix field supports + for ( int isNode = 0; isNode < 2; ++isNode ) + { + std::vector& fields = isNode ? _nodeFields : _cellFields; + for ( size_t i = 0; i < fields.size(); ++i ) + { + if ( !fields[i] ) continue; + for ( size_t j = 0; j < fields[i]->_sub.size(); ++j ) + if ( fields[i]->_sub[j]._support ) + { + int iG = fields[i]->_sub[j]._support - &_groups[0]; + fields[i]->_sub[j]._support = & newGroups[ iG ]; + } + if ( fields[i]->_group ) + { + int iG = fields[i]->_group - &_groups[0]; + fields[i]->_group = & newGroups[ iG ]; + } + } + } + + _groups.swap( newGroups ); + } + else + { + _groups.push_back( Group() ); + } + return &_groups.back(); +} + //================================================================================ /*! * \brief Makes ParaMEDMEM::MEDFileData from self diff --git a/src/MEDLoader/SauvMedConvertor.hxx b/src/MEDLoader/SauvMedConvertor.hxx index 50bcc3604..fa16a1293 100644 --- a/src/MEDLoader/SauvMedConvertor.hxx +++ b/src/MEDLoader/SauvMedConvertor.hxx @@ -94,7 +94,6 @@ namespace SauvUtilities std::string _name; std::vector _cells; std::vector< Group* > _groups; // des sous-groupes composant le Group - //bool _isShared; // true if any Cell was added to the mesh from other Group bool _isProfile; // is a field support or not std::vector _refNames; /* names of groups referring this one; _refNames is resized according to nb of references @@ -255,6 +254,7 @@ namespace SauvUtilities Node* getNode( TID nID ) { return _points.getNode( nID ); } int getNbCellsOfType( TCellType type ) const { return _cellsByType[type].size(); } const Cell* insert(TCellType type, const Cell& ma) { return &( *_cellsByType[type].insert( ma ).first ); } + Group* addNewGroup(std::vector* groupsToFix=0); ParaMEDMEM::MEDFileData* convertInMEDFileDS(); private: diff --git a/src/MEDLoader/SauvReader.cxx b/src/MEDLoader/SauvReader.cxx index 848d5e4c2..55a488303 100644 --- a/src/MEDLoader/SauvReader.cxx +++ b/src/MEDLoader/SauvReader.cxx @@ -428,9 +428,9 @@ void SauvReader::read_PILE_SOUS_MAILLAGE(const int nbObjects, SauvUtilities::Group & grp = _iMed->_groups[ grpID-1 ]; if ( !grp._name.empty() ) // a group has several names { // create a group with subgroup grp and named grp.name - _iMed->_groups.push_back(Group()); - _iMed->_groups.back()._groups.push_back( &_iMed->_groups[ grpID-1 ]); - _iMed->_groups.back()._name = grp._name; + SauvUtilities::Group* newGroup = _iMed->addNewGroup(); + newGroup->_groups.push_back( &_iMed->_groups[ grpID-1 ]); + newGroup->_name = grp._name; } grp._name=objectNames[i]; #ifdef _DEBUG @@ -688,8 +688,7 @@ void SauvReader::setFieldSupport(const vector& supports, sameOrder = ( supports[j] == newGroups[ j % newGroups.size() ]); if ( sameOrder ) { - _iMed->_groups.push_back( SauvUtilities::Group() ); - group = & _iMed->_groups.back(); + group = _iMed->addNewGroup( & newGroups ); group->_groups.swap( newGroups ); } } -- 2.39.2