Coverage Report

Created: 2025-08-29 06:37

/src/testdir/tests/capi/lua_load_test.cc
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * SPDX-License-Identifier: ISC
3
 *
4
 * Copyright 2023, Sergey Bronnikov.
5
 */
6
7
#include <assert.h>
8
#include <string.h>
9
10
#if defined(__cplusplus)
11
extern "C" {
12
#endif /* defined(__cplusplus) */
13
14
#include "lua.h"
15
#include "lualib.h"
16
#include "lauxlib.h"
17
18
#if defined(__cplusplus)
19
} /* extern "C" */
20
#endif /* defined(__cplusplus) */
21
22
#include <fuzzer/FuzzedDataProvider.h>
23
24
typedef struct {
25
  FuzzedDataProvider *fdp;
26
} dt;
27
28
static const char *
29
Reader(lua_State *L, void *data, size_t *size)
30
1.01M
{
31
1.01M
  dt *test_data = (dt *)data;
32
1.01M
  static char *buf = NULL;
33
34
1.01M
  FuzzedDataProvider *fdp = test_data->fdp;
35
1.01M
  uint8_t max_str_size = fdp->ConsumeIntegral<uint8_t>();
36
1.01M
  if (fdp->remaining_bytes() < max_str_size)
37
1.21k
    return NULL;
38
1.00M
  auto str = fdp->ConsumeRandomLengthString(max_str_size);
39
1.00M
  *size = str.size();
40
41
1.00M
  free(buf);
42
1.00M
  buf = (char *)malloc(*size);
43
1.00M
  assert(buf);
44
1.00M
  memcpy(buf, str.c_str(), *size);
45
46
1.00M
  return buf;
47
1.00M
}
48
49
extern "C" int
50
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
51
4.29k
{
52
4.29k
  lua_State *L = luaL_newstate();
53
4.29k
  if (L == NULL)
54
0
    return 0;
55
56
4.29k
  luaL_openlibs(L);
57
58
4.29k
  FuzzedDataProvider fdp(data, size);
59
4.29k
  dt test_data;
60
4.29k
  test_data.fdp = &fdp;
61
62
#if LUA_VERSION_NUM == 501
63
  int res = lua_load(L, Reader, &test_data, "libFuzzer");
64
#else /* Lua 5.3+ */
65
4.29k
  const char *mode = "t";
66
4.29k
  int res = lua_load(L, Reader, &test_data, "libFuzzer", mode);
67
4.29k
#endif /* LUA_VERSION_NUM */
68
4.29k
  if (res == LUA_OK) {
69
3.21k
    lua_pcall(L, 0, 0, 0);
70
3.21k
  }
71
72
4.29k
  lua_settop(L, 0);
73
4.29k
  lua_close(L);
74
75
4.29k
  return 0;
76
4.29k
}