Commit Diff


commit - 847dd20811eb947fa67fb6e3c076f815f80d1a51
commit + 0d927a36f0b8d71f12717eb1a7327cfc42a6a51c
blob - 1c304d5b09927c1b1034ca87595766651c44ab11
blob + 5c41b700cf04b2fe115da766ad718a50117efaae
--- CHANGELOG.md
+++ CHANGELOG.md
@@ -13,3 +13,4 @@ and this project adheres to [Semantic Versioning](http
 - Integration with libFuzzer's `LLVMFuzzerCustomMutator()`.
 - Integration with libFuzzer's `FuzzedDataProvider`.
 - libFuzzer custom mutator for Lua.
+- Examples with tests.
blob - f6587371ddb17cb67ea6740fce29f8dd5494d7cb
blob + 9b1e464b025503eb39f5261821a06aadf97fdf6a
--- luzer/tests/CMakeLists.txt
+++ luzer/tests/CMakeLists.txt
@@ -28,3 +28,24 @@ set_tests_properties(luzer_options_test PROPERTIES
   ENVIRONMENT "LUA_CPATH='${LUA_CPATH}'"
   PASS_REGULAR_EXPRESSION "ERROR: The required directory \"undefined\" does not exist"
 )
+
+add_test(
+  NAME luzer_custom_mutator_example
+  COMMAND ${LUA_EXECUTABLE} "${PROJECT_SOURCE_DIR}/examples/example_custom_mutator.lua"
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+set_tests_properties(luzer_custom_mutator_example PROPERTIES
+  ENVIRONMENT "LUA_CPATH='${LUA_CPATH}'"
+  PASS_REGULAR_EXPRESSION "example_custom_mutator.lua:19: assert has triggered"
+)
+
+add_test(
+  NAME luzer_basic_example
+  COMMAND ${LUA_EXECUTABLE} "${PROJECT_SOURCE_DIR}/examples/example_basic.lua"
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+set_tests_properties(luzer_basic_example PROPERTIES
+  ENVIRONMENT "LUA_CPATH='${LUA_CPATH}'"
+  PASS_REGULAR_EXPRESSION "example_custom_mutator.lua:19: assert has triggered"
+  DISABLED True
+)
blob - /dev/null
blob + 2418e70235aad4d19b58b38d727e644392cefc8a (mode 644)
--- /dev/null
+++ examples/example_basic.lua
@@ -0,0 +1,22 @@
+local luzer = require("luzer")
+
+local function TestOneInput(buf)
+    local fdp = luzer.FuzzedDataProvider(buf)
+    local str = fdp:consume_string(4)
+
+    local b = {}
+    str:gsub(".", function(c) table.insert(b, c) end)
+    local count = 0
+    if b[1] == "o" then count = count + 1 end
+    if b[2] == "o" then count = count + 1 end
+    if b[3] == "p" then count = count + 1 end
+    if b[4] == "s" then count = count + 1 end
+
+    if count == 4 then assert(nil) end
+end
+
+local args = {
+    only_ascii = 1,
+    print_pcs = 1,
+}
+luzer.Fuzz(TestOneInput, nil, args)
blob - /dev/null
blob + ee7c621fed098fe0d7491361c69e0c0e0d1f523a (mode 644)
--- /dev/null
+++ examples/example_custom_mutator.lua
@@ -0,0 +1,29 @@
+local luzer = require("luzer")
+
+local function custom_mutator(buf)
+    return buf .. "A"
+end
+
+local function TestOneInput(buf)
+    local fdp = luzer.FuzzedDataProvider(buf)
+    local str = fdp:consume_string(3)
+
+    local b = {}
+    str:gsub(".", function(c)
+        table.insert(b, c)
+    end)
+
+    if b[1] == "A" then
+        if b[2] == "A" then
+            if b[3] == "A" then
+                assert(nil, "assert has triggered")
+            end
+        end
+    end
+end
+
+local args = {
+    only_ascii = 1,
+}
+
+luzer.Fuzz(TestOneInput, custom_mutator, args)
blob - /dev/null
blob + 12b1c4e7199f6aa21ee58452a0851ec5ad633795 (mode 644)
--- /dev/null
+++ examples/example_ffi_zlib.lua
@@ -0,0 +1,48 @@
+-- https://luajit.org/ext_ffi_tutorial.html
+
+local luzer = require("luzer")
+local has_ffi, ffi = pcall(require, "ffi")
+
+if not has_ffi then
+    print("ffi is not found")
+    os.exit(1)
+end
+
+ffi.cdef[[
+unsigned long compressBound(unsigned long sourceLen);
+int compress2(uint8_t *dest, unsigned long *destLen,
+	      const uint8_t *source, unsigned long sourceLen, int level);
+int uncompress(uint8_t *dest, unsigned long *destLen,
+	       const uint8_t *source, unsigned long sourceLen);
+]]
+local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z")
+
+local function compress(txt)
+    local n = zlib.compressBound(#txt)
+    local buf = ffi.new("uint8_t[?]", n)
+    local buflen = ffi.new("unsigned long[1]", n)
+    local res = zlib.compress2(buf, buflen, txt, #txt, 9)
+    assert(res == 0)
+    return ffi.string(buf, buflen[0])
+end
+
+local function uncompress(comp, n)
+    local buf = ffi.new("uint8_t[?]", n)
+    local buflen = ffi.new("unsigned long[1]", n)
+    local res = zlib.uncompress(buf, buflen, comp, #comp)
+    assert(res == 0)
+    return ffi.string(buf, buflen[0])
+end
+
+local function TestOneInput(buf)
+    local compressed = compress(buf)
+    if compressed ~= nil then
+        local raw = uncompress(compressed, #buf)
+        assert(raw == buf)
+    end
+end
+
+local args = {
+    max_len = 4096,
+}
+luzer.Fuzz(TestOneInput, nil, args)