[libc-commits] [libc] [libc] add hashtable fuzzing (PR #87949)

via libc-commits libc-commits at lists.llvm.org
Wed May 1 08:56:52 PDT 2024


================
@@ -0,0 +1,180 @@
+//===-- hashtable_fuzz.cpp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// Fuzzing test for llvm-libc hashtable implementations.
+///
+//===----------------------------------------------------------------------===//
+#include "include/llvm-libc-types/ENTRY.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/HashTable/table.h"
+
+namespace LIBC_NAMESPACE {
+
+// A fuzzing payload starts with
+// - uint16_t: initial capacity for table A
+// - uint64_t: seed for table A
+// - uint16_t: initial capacity for table B
+// - uint64_t: seed for table B
+// Followed by a sequence of actions:
+// - CrossCheck: only a single byte valued 3
+// - Find: a single byte valued 0 followed by a null-terminated string
+// - Insert: a single byte valued 1 followed by a null-terminated string
+static constexpr size_t INITIAL_HEADER_SIZE =
+    2 * (sizeof(uint16_t) + sizeof(uint64_t));
+extern "C" size_t LLVMFuzzerMutate(uint8_t *data, size_t size, size_t max_size);
+extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size,
+                                          size_t max_size, unsigned int seed) {
+  size = LLVMFuzzerMutate(data, size, max_size);
+  // not enough to read the initial capacities and seeds
+  if (size < INITIAL_HEADER_SIZE)
+    return 0;
+
+  // skip the initial capacities and seeds
+  size_t i = INITIAL_HEADER_SIZE;
+  while (i < size) {
+    switch (data[i] % 3) {
+    case 2:
+      // cross check
+      break;
+
+    default:
+      // find or insert
+      // check if there is enough space for the action byte and the
+      // null-terminator
+      if (i + 2 >= max_size)
+        return i;
+      // skip the action byte
+      ++i;
+      // skip the null-terminated string
+      while (i < max_size && data[i] != 0)
+        ++i;
+      // in the case the string is not null-terminated, null-terminate it
+      if (i == max_size && data[i - 1] != 0)
+        data[i - 1] = 0;
+      break;
+    }
+    // move to the next action
+    ++i;
+  }
----------------
lntue wrote:

Will this be easier to read for this loop?
```
for (; i < size; ++i) {
  if (data[i] % 3 == 2)
    continue;
  // the remaining of the default clause.
}
```

https://github.com/llvm/llvm-project/pull/87949


More information about the libc-commits mailing list