@@ -16,6 +16,11 @@ type MemoryKVVal is bytes32;
1616
1717/// @title LibMemoryKV
1818library LibMemoryKV {
19+ /// Thrown when the memory allocation for a new key/value pair would exceed
20+ /// the maximum pointer value of `0xFFFF` which would cause corruption of
21+ /// the linked list and potentially overwriting of unrelated memory.
22+ error MemoryKVOverflow (uint256 pointer );
23+
1924 /// Gets the value associated with a given key.
2025 /// The value returned will be `0` if the key exists and was set to zero OR
2126 /// the key DOES NOT exist, i.e. was never set.
@@ -59,6 +64,7 @@ library LibMemoryKV {
5964 /// @return The final value of `kv` as it MAY be modified if the upsert
6065 /// resulted in an insert operation.
6166 function set (MemoryKV kv , MemoryKVKey key , MemoryKVVal value ) internal pure returns (MemoryKV) {
67+ uint256 pointer;
6268 assembly ("memory-safe" ) {
6369 // Hash to spread inserts across internal lists.
6470 // This MUST remain in sync with `get` logic.
@@ -70,7 +76,7 @@ library LibMemoryKV {
7076 let startPointer := and (shr (bitOffset, kv), 0xFFFF )
7177
7278 // Find a key match then break so that we populate a nonzero pointer.
73- let pointer := startPointer
79+ pointer := startPointer
7480 for {} iszero (iszero (pointer)) { pointer := mload (add (pointer, 0x40 )) } {
7581 if eq (key, mload (pointer)) { break }
7682 }
@@ -106,6 +112,9 @@ library LibMemoryKV {
106112 )
107113 }
108114 }
115+ if (pointer > 0xFFFF ) {
116+ revert MemoryKVOverflow (pointer);
117+ }
109118 return kv;
110119 }
111120
0 commit comments