]> code.citadel.org Git - citadel.git/blobdiff - libcitadel/lib/hash.c
* off by one in range checking of indexed access
[citadel.git] / libcitadel / lib / hash.c
index 2eb5e1a0d11f77834c4a7c55f949dcf42d8bdbe7..bd22f10a8f35df74d5c1a58e68c7a1e379f7ff38 100644 (file)
@@ -651,8 +651,8 @@ int DeleteEntryFromHash(HashList *Hash, HashPos *At)
                return 0;
        }
 
-       FreeMe = Hash->Members[At->Position];
-       Hash->Members[At->Position] = NULL;
+       FreeMe = Hash->Members[Hash->LookupTable[At->Position]->Position];
+       Hash->Members[Hash->LookupTable[At->Position]->Position] = NULL;
 
 
        /** delete our hashing data */
@@ -667,6 +667,7 @@ int DeleteEntryFromHash(HashList *Hash, HashPos *At)
                                (Hash->nLookupTableItems - At->Position - 1) * 
                                sizeof(HashKey*));
 
+                       Hash->LookupTable[Hash->nLookupTableItems - 1] = NULL;
                }
                else 
                        Hash->LookupTable[At->Position] = NULL;
@@ -715,6 +716,7 @@ void DeleteHashPos(HashPos **DelMe)
 /**
  * @brief Get the data located where HashPos Iterator points at, and Move HashPos one forward
  * @param Hash your Hashlist to follow
+ * @param At the position to retrieve the Item from and move forward afterwards
  * @param HKLen returns Length of Hashkey Returned
  * @param HashKey returns the Hashkey corrosponding to HashPos
  * @param Data returns the Data found at HashPos
@@ -743,6 +745,57 @@ int GetNextHashPos(HashList *Hash, HashPos *At, long *HKLen, const char **HashKe
        return 1;
 }
 
+/**
+ * @brief Get the data located where HashPos Iterator points at
+ * @param Hash your Hashlist to follow
+ * @param At the position retrieve the data from
+ * @param HKLen returns Length of Hashkey Returned
+ * @param HashKey returns the Hashkey corrosponding to HashPos
+ * @param Data returns the Data found at HashPos
+ * \returns whether the item was found or not.
+ */
+int GetHashPos(HashList *Hash, HashPos *At, long *HKLen, const char **HashKey, void **Data)
+{
+       long PayloadPos;
+
+       if ((Hash == NULL) || 
+           (At->Position >= Hash->nLookupTableItems) || 
+           (At->Position < 0) ||
+           (At->Position > Hash->nLookupTableItems))
+               return 0;
+       *HKLen = Hash->LookupTable[At->Position]->HKLen;
+       *HashKey = Hash->LookupTable[At->Position]->HashKey;
+       PayloadPos = Hash->LookupTable[At->Position]->Position;
+       *Data = Hash->Members[PayloadPos]->Data;
+
+       return 1;
+}
+
+/**
+ * @brief Move HashPos one forward
+ * @param Hash your Hashlist to follow
+ * @param At the position to move forward
+ * \returns whether there is a next item or not.
+ */
+int NextHashPos(HashList *Hash, HashPos *At)
+{
+       if ((Hash == NULL) || 
+           (At->Position >= Hash->nLookupTableItems) || 
+           (At->Position < 0) ||
+           (At->Position > Hash->nLookupTableItems))
+               return 0;
+
+       /* Position is NULL-Based, while Stepwidth is not... */
+       if ((At->Position % abs(At->StepWidth)) == 0)
+               At->Position += At->StepWidth;
+       else 
+               At->Position += ((At->Position) % abs(At->StepWidth)) * 
+                       (At->StepWidth / abs(At->StepWidth));
+       return !((At->Position >= Hash->nLookupTableItems) || 
+                (At->Position < 0) ||
+                (At->Position > Hash->nLookupTableItems));
+}
+
 /**
  * @brief Get the data located where At points to
  * note: you should prefer iterator operations instead of using me.
@@ -758,7 +811,7 @@ int GetHashAt(HashList *Hash,long At, long *HKLen, const char **HashKey, void **
 
        if ((Hash == NULL) || 
            (At < 0) || 
-           (At > Hash->nLookupTableItems))
+           (At >= Hash->nLookupTableItems))
                return 0;
        *HKLen = Hash->LookupTable[At]->HKLen;
        *HashKey = Hash->LookupTable[At]->HashKey;
@@ -902,15 +955,6 @@ void SortByPayload(HashList *Hash, CompareFunc SortBy)
  */
 
 
-/*
- * Generic function to free a pointer.  This can be used as a callback with the
- * hash table, even on systems where free() is defined as a macro or has had other
- * horrible things done to it.
- */
-void generic_free_handler(void *ptr) {
-       free(ptr);
-}
-
 /*
  * Generic function to free a reference.  
  * since a reference actualy isn't needed to be freed, do nothing.