0030518: Foundation Classes - NCollection_IndexedDataMap array out of bounds
[occt.git] / src / NCollection / NCollection_IndexedDataMap.hxx
index 45fa17d..c3a7f4b 100644 (file)
@@ -95,49 +95,51 @@ private:
     //! Empty constructor
     Iterator()
     : myMap (NULL),
-      myNode (NULL),
       myIndex (0) {}
+
     //! Constructor
     Iterator (const NCollection_IndexedDataMap& theMap)
-    : myMap  ((NCollection_IndexedDataMap* )&theMap),
-      myNode (!theMap.IsEmpty() ? (IndexedDataMapNode* )myMap->myData2[0] : NULL),
+    : myMap ((NCollection_IndexedDataMap*)&theMap),
       myIndex (1) {}
+
     //! Query if the end of collection is reached by iterator
     Standard_Boolean More(void) const
     { return (myMap != NULL) && (myIndex <= myMap->Extent()); }
+
     //! Make a step along the collection
     void Next(void)
-    {
-      myNode = (IndexedDataMapNode* )myMap->myData2[++myIndex - 1];
-    }
+    { ++myIndex; }
+
     //! Value access
     const TheItemType& Value(void) const
     {  
       Standard_NoSuchObject_Raise_if(!More(), "NCollection_IndexedDataMap::Iterator::Value");
-      return myNode->Value();
+      return myMap->FindFromIndex(myIndex);
     }
+
     //! ChangeValue access
     TheItemType& ChangeValue(void) const
     {  
       Standard_NoSuchObject_Raise_if(!More(), "NCollection_IndexedDataMap::Iterator::ChangeValue");
-      return myNode->ChangeValue();
+      return myMap->ChangeFromIndex(myIndex);
     }
+
     //! Key
     const TheKeyType& Key() const
     {
       Standard_NoSuchObject_Raise_if(!More(), "NCollection_IndexedDataMap::Iterator::Key");
-      return myNode->Key1();
+      return myMap->FindKey(myIndex);
     }
+
     //! Performs comparison of two iterators.
     Standard_Boolean IsEqual (const Iterator& theOther) const
     {
       return myMap == theOther.myMap &&
-             myNode == theOther.myNode &&
              myIndex == theOther.myIndex;
     }
+
   private:
-    NCollection_IndexedDataMap* myMap;   //!< Pointer to the map being iterated
-    IndexedDataMapNode*         myNode;  //!< Current node
+    NCollection_IndexedDataMap* myMap;   //!< Pointer to current node
     Standard_Integer            myIndex; //!< Current index
   };
   
@@ -190,16 +192,20 @@ private:
       return *this;
 
     Clear();
-    ReSize (theOther.Extent()-1);
-    for (Standard_Integer anIndexIter = 1; anIndexIter <= theOther.Extent(); ++anIndexIter)
+    Standard_Integer anExt = theOther.Extent();
+    if (anExt)
     {
-      const TheKeyType&  aKey1  = theOther.FindKey      (anIndexIter);
-      const TheItemType& anItem = theOther.FindFromIndex(anIndexIter);
-      const Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
-      IndexedDataMapNode* pNode = new (this->myAllocator) IndexedDataMapNode (aKey1, anIndexIter, anItem, myData1[iK1]);
-      myData1[iK1]             = pNode;
-      myData2[anIndexIter - 1] = pNode;
-      Increment();
+      ReSize (anExt-1); //mySize is same after resize
+      for (Standard_Integer anIndexIter = 1; anIndexIter <= anExt; ++anIndexIter)
+      {
+        const TheKeyType&  aKey1  = theOther.FindKey      (anIndexIter);
+        const TheItemType& anItem = theOther.FindFromIndex(anIndexIter);
+        const Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
+        IndexedDataMapNode* pNode = new (this->myAllocator) IndexedDataMapNode (aKey1, anIndexIter, anItem, myData1[iK1]);
+        myData1[iK1]             = pNode;
+        myData2[anIndexIter - 1] = pNode;
+        Increment();
+      }
     }
     return *this;
   }
@@ -241,7 +247,10 @@ private:
     }
   }
 
-  //! Add
+  //! Returns the Index of already bound Key or appends new Key with specified Item value.
+  //! @param theKey1 Key to search (and to bind, if it was not bound already)
+  //! @param theItem Item value to set for newly bound Key; ignored if Key was already bound
+  //! @return index of Key
   Standard_Integer Add (const TheKeyType& theKey1, const TheItemType& theItem)
   {
     if (Resizable())