0027941: Foundation Classes - NCollection_Vector::Iterator::offsetV() does not match...
authorkgv <kgv@opencascade.com>
Fri, 7 Oct 2016 15:49:34 +0000 (18:49 +0300)
committerapn <apn@opencascade.com>
Thu, 13 Oct 2016 10:43:07 +0000 (13:43 +0300)
src/NCollection/NCollection_BaseVector.hxx
src/QANCollection/QANCollection_Stl.cxx

index c0a93ec..08c6a61 100755 (executable)
@@ -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
index d467f1f..e3f08b6 100644 (file)
@@ -822,6 +822,30 @@ static Standard_Integer QANVectorStlIterator (Draw_Interpretor&, Standard_Intege
   std::cout << "NCollection_Vector<double> 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<int> aVector (THE_INCREMENT);
+    for (int anIter = 0; anIter < THE_INCREMENT; ++anIter)
+    {
+      aVector.Append (THE_INCREMENT - anIter);
+    }
+
+    NCollection_Vector<int>::iterator aBegin = aVector.begin();
+    NCollection_Vector<int>::iterator anEnd  = aVector.end();
+    NCollection_Vector<int>::iterator aShift = aBegin + THE_INCREMENT;
+    aResult = (aShift == anEnd);
+    std::cout << "NCollection_Vector<int> Offset:                 " <<
+      (aResult ? "SUCCESS" : "FAIL") << std::endl;
+
+    std::stable_sort (aVector.begin(), aVector.end());
+  }
+
   return 0;
 }