diff --git a/src/NCollection/NCollection_BaseVector.hxx b/src/NCollection/NCollection_BaseVector.hxx index c0a93ec97c..08c6a61615 100755 --- a/src/NCollection/NCollection_BaseVector.hxx +++ b/src/NCollection/NCollection_BaseVector.hxx @@ -117,6 +117,13 @@ protected: const Standard_Integer anIndex = myCurIndex + myICurBlock * myVector->myIncrement + theOffset; myICurBlock = anIndex / myVector->myIncrement; myCurIndex = anIndex % myVector->myIncrement; + if (myICurBlock > myIEndBlock) + { + // make sure that iterator produced by Offset() + // is equal to the end() iterator + --myICurBlock; + myCurIndex += myVector->myIncrement; + } } Standard_Integer differV (const Iterator& theOther) const diff --git a/src/QANCollection/QANCollection_Stl.cxx b/src/QANCollection/QANCollection_Stl.cxx index d467f1fb5f..e3f08b6489 100644 --- a/src/QANCollection/QANCollection_Stl.cxx +++ b/src/QANCollection/QANCollection_Stl.cxx @@ -822,6 +822,30 @@ static Standard_Integer QANVectorStlIterator (Draw_Interpretor&, Standard_Intege std::cout << "NCollection_Vector Parallel: " << (aResult ? "SUCCESS" : "FAIL") << std::endl; + { + // Test case for a corner case described in a bug #0027941 + // when vector length matches the increment. + // In this case NCollection_Vector::Iterator::Offset() produced mathematically equal + // but not the same iterator as returned by NCollection_Vector::end() + // so that their comparison was not equal. + // As result, std::stable_sort() crashed due to out-of-range access. + const int THE_INCREMENT = 256; + NCollection_Vector aVector (THE_INCREMENT); + for (int anIter = 0; anIter < THE_INCREMENT; ++anIter) + { + aVector.Append (THE_INCREMENT - anIter); + } + + NCollection_Vector::iterator aBegin = aVector.begin(); + NCollection_Vector::iterator anEnd = aVector.end(); + NCollection_Vector::iterator aShift = aBegin + THE_INCREMENT; + aResult = (aShift == anEnd); + std::cout << "NCollection_Vector Offset: " << + (aResult ? "SUCCESS" : "FAIL") << std::endl; + + std::stable_sort (aVector.begin(), aVector.end()); + } + return 0; }