Browse Source

Size check for list

Kajetan Johannes Hammerle 2 months ago
parent
commit
55f682838d

+ 10 - 3
include/core/data/List.hpp

@@ -195,9 +195,16 @@ namespace Core {
         }
 
         check_return Error ensureCapacity() {
-            return length >= capacity
-                       ? reserve(capacity + Core::Math::max(4, capacity / 4))
-                       : Error::NONE;
+            if(length == CORE_INT_MAX) {
+                return Error::CAPACITY_REACHED;
+            } else if(length < capacity) {
+                return Error::NONE;
+            }
+            int add = Core::Math::max(4, capacity / 4);
+            if(capacity > CORE_INT_MAX - add) {
+                return reserve(CORE_INT_MAX);
+            }
+            return reserve(capacity + add);
         }
 
         // does not check for capacity

+ 10 - 8
include/core/data/ProbingHashMap.hpp

@@ -298,14 +298,16 @@ namespace Core {
 
         template<typename Value>
         Value* searchValue(const K& key) const {
-            u32 baseHash = hashCode(key) * 514685581u;
-            u32 end = static_cast<u32>(keys.getLength()) - 1;
-            for(u32 i = 0; i <= end; i++) [[unlikely]] {
-                int hash = static_cast<int>((baseHash + i) & end);
-                if(keys[hash] == key) [[likely]] {
-                    return values + hash;
-                } else if(keys[hash] == emptyValue<K>()) {
-                    return nullptr;
+            if(keys.getLength() != 0) {
+                u32 baseHash = hashCode(key) * 514685581u;
+                u32 end = static_cast<u32>(keys.getLength()) - 1;
+                for(u32 i = 0; i <= end; i++) [[unlikely]] {
+                    int hash = static_cast<int>((baseHash + i) & end);
+                    if(keys[hash] == key) [[likely]] {
+                        return values + hash;
+                    } else if(keys[hash] == emptyValue<K>()) {
+                        return nullptr;
+                    }
                 }
             }
             return nullptr;

+ 7 - 0
include/core/utils/Types.hpp

@@ -1,6 +1,7 @@
 #ifndef CORE_TYPES_HPP
 #define CORE_TYPES_HPP
 
+#include <limits.h>
 #include <stdint.h>
 
 using i64 = int64_t;
@@ -13,4 +14,10 @@ using u16 = uint16_t;
 using u8 = uint8_t;
 using c32 = char32_t;
 
+// user customizable max container size
+#ifndef CORE_INT_MAX
+#define CORE_INT_MAX 65535
+#endif
+static_assert(CORE_INT_MAX < INT_MAX, "custom int max too large");
+
 #endif

+ 10 - 0
test/modules/ListTests.cpp

@@ -212,6 +212,15 @@ static void testCopyEmpty() {
     CORE_TEST_ERROR(copy.copyFrom(list));
 }
 
+static void testOverflow() {
+    IntList list;
+    for(int i = 0; i < CORE_INT_MAX; i++) {
+        CORE_TEST_ERROR(list.add(i));
+    }
+    CORE_TEST_EQUAL(Core::Error::CAPACITY_REACHED, list.add(1));
+    CORE_TEST_EQUAL(CORE_INT_MAX, list.getCapacity());
+}
+
 void Core::testList(bool light) {
     testAdd();
     testMultipleAdd();
@@ -233,4 +242,5 @@ void Core::testList(bool light) {
     testShrinkExact();
     testShrinkResize();
     testCopyEmpty();
+    testOverflow();
 }