0030518: Foundation Classes - NCollection_IndexedDataMap array out of bounds
authorabv <abv@opencascade.com>
Mon, 16 Sep 2019 05:01:13 +0000 (08:01 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 20 Sep 2019 16:39:30 +0000 (19:39 +0300)
Implementation of NCollection_IndexedDataMap::Iterator is revised to avoid unintended access to the element out of array bounds

src/NCollection/NCollection_BaseMap.cxx
src/NCollection/NCollection_IndexedDataMap.hxx

index 60754c5..dcaa1e7 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <NCollection_BaseMap.hxx>
 #include <TCollection.hxx>
+#include <Standard_Assert.hxx>
 
 //=======================================================================
 //function : BeginResize
@@ -29,20 +30,17 @@ Standard_Boolean  NCollection_BaseMap::BeginResize
    NCollection_ListNode**& data1,
    NCollection_ListNode**& data2) const 
 {
+  // get next size for the buckets array
   N = NextPrimeForMap(NbBuckets);
-  if (N <= myNbBuckets) {
-    if (!myData1)
-      N = myNbBuckets;
-    else
-      return Standard_False;
-  }
+  Standard_ASSERT (N > NbBuckets, "NextPrimeForMap failed to return valid number", return Standard_False);
+
   data1 = (NCollection_ListNode **)
     myAllocator->Allocate((N+1)*sizeof(NCollection_ListNode *));
   memset(data1, 0, (N+1)*sizeof(NCollection_ListNode *));
   if (isDouble) 
   {
     data2 = (NCollection_ListNode **)
-    myAllocator->Allocate((N+1)*sizeof(NCollection_ListNode *));
+      myAllocator->Allocate((N+1)*sizeof(NCollection_ListNode *));
     memset(data2, 0, (N+1)*sizeof(NCollection_ListNode *));
   }
   else
index 7f1f823..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
   };