Coverage Report

Created: 2025-07-18 07:03

/src/testdir/tests/capi/torture_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
/**
8
 * Each Lua C API function has an indicator like this: [-o, +p, x],
9
 * see "4.6 – Functions and Types" in Lua Reference Manual.
10
 *
11
 * The test pushes random Lua objects to a Lua stack, runs random Lua C API
12
 * functions and checks that executed function conforms to its function
13
 * indicator.
14
 */
15
16
#include <assert.h>
17
#include <stdint.h>
18
19
#include <fuzzer/FuzzedDataProvider.h>
20
21
#if defined(__cplusplus)
22
extern "C" {
23
#endif /* defined(__cplusplus) */
24
25
#include "lua.h"
26
#include "lualib.h"
27
#include "lauxlib.h"
28
29
#if defined(__cplusplus)
30
} /* extern "C" */
31
#endif /* defined(__cplusplus) */
32
33
11.5k
#define ARRAY_SIZE(arr)     (sizeof(arr) / sizeof((arr)[0]))
34
35
static int max_str_len = 1;
36
37
static int
38
57
cfunction(lua_State *L) {
39
57
  lua_gettop(L);
40
57
  return 0;
41
57
}
42
43
2.37k
#define TYPE_NAME_TORTURE "torture_test"
44
23
#define MT_FUNC_NAME_TORTURE "__torture"
45
46
static const luaL_Reg TORTURE_meta[] =
47
{
48
  { MT_FUNC_NAME_TORTURE, cfunction },
49
  { 0, 0 }
50
};
51
52
/* void lua_pushstring(lua_State *L, const char *s); */
53
/* [-0, +1, m] */
54
static void
55
__lua_pushstring(lua_State *L, FuzzedDataProvider *fdp)
56
154
{
57
154
  auto str = fdp->ConsumeRandomLengthString(max_str_len);
58
154
  int top = lua_gettop(L);
59
154
  lua_pushstring(L, str.c_str());
60
154
  assert(lua_gettop(L) == top + 1);
61
154
}
62
63
/* void lua_pushboolean(lua_State *L, int b); */
64
/* [-0, +1, -] */
65
static void
66
__lua_pushboolean(lua_State *L, FuzzedDataProvider *fdp)
67
91
{
68
91
  uint8_t n = fdp->ConsumeIntegral<uint8_t>();
69
91
  int top = lua_gettop(L);
70
91
  lua_pushboolean(L, n);
71
91
  assert(lua_gettop(L) == top + 1);
72
91
}
73
74
/* void lua_pop(lua_State *L, int n); */
75
/* [-n, +0, -] */
76
static void
77
__lua_pop(lua_State *L, FuzzedDataProvider *fdp)
78
12
{
79
12
  int top = lua_gettop(L);
80
12
  uint8_t n = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
81
12
  lua_pop(L, n);
82
12
  assert(lua_gettop(L) == top - n);
83
12
}
84
85
/* int lua_isnumber(lua_State *L, int index); */
86
/* [-0, +0, -] */
87
static void
88
__lua_isnumber(lua_State *L, FuzzedDataProvider *fdp)
89
25
{
90
25
  int top = lua_gettop(L);
91
25
  uint8_t n = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
92
25
  lua_isnumber(L, n);
93
25
  assert(lua_gettop(L) == top);
94
25
}
95
96
/* lua_Number lua_tonumber(lua_State *L, int index); */
97
/* [-0, +0, -] */
98
static void
99
__lua_tonumber(lua_State *L, FuzzedDataProvider *fdp)
100
9
{
101
9
  int top = lua_gettop(L);
102
9
  uint8_t n = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
103
9
  lua_tonumber(L, n);
104
9
  assert(lua_gettop(L) == top);
105
9
}
106
107
/* lua_Number lua_tonumberx(lua_State *L, int index, int *isnum); */
108
/* [-0, +0, –] */
109
static void
110
__lua_tonumberx(lua_State *L, FuzzedDataProvider *fdp)
111
27
{
112
27
  int top = lua_gettop(L);
113
27
  auto index = fdp->ConsumeIntegralInRange(1, top);
114
27
  int isnum;
115
27
  lua_tonumberx(L, index, &isnum);
116
27
  assert(isnum == 0 || isnum == 1);
117
27
  assert(lua_gettop(L) == top);
118
27
}
119
120
/* int lua_checkstack(lua_State *L, int extra); */
121
/* [-0, +0, m] */
122
static void
123
__lua_checkstack(lua_State *L, FuzzedDataProvider *fdp)
124
46
{
125
46
  uint8_t n = fdp->ConsumeIntegral<uint8_t>();
126
46
  int rc = lua_checkstack(L, n);
127
46
  assert(rc != 0);
128
46
}
129
130
/* void lua_concat(lua_State *L, int n); */
131
/* [-n, +1, e] */
132
static void
133
__lua_concat(lua_State *L, FuzzedDataProvider *fdp)
134
50
{
135
50
  int top = lua_gettop(L);
136
50
  uint8_t n = fdp->ConsumeIntegralInRange<uint8_t>(0, top);
137
94
  for (int i = 1; i <= n; i++) {
138
64
    int t = lua_type(L, -i);
139
64
    if (t != LUA_TNUMBER &&
140
64
        t != LUA_TSTRING)
141
20
      return;
142
64
  }
143
30
  lua_concat(L, n);
144
30
  assert(lua_gettop(L) == top - n + 1);
145
30
}
146
147
/* int lua_gettop(lua_State *L); */
148
/* [-0, +0, -] */
149
static void
150
__lua_gettop(lua_State *L, FuzzedDataProvider *fdp)
151
3
{
152
3
  int rc = lua_gettop(L);
153
3
  assert(rc >= 0);
154
3
}
155
156
/* void lua_insert(lua_State *L, int index); */
157
/* [-1, +1, -] */
158
static void
159
__lua_insert(lua_State *L, FuzzedDataProvider *fdp)
160
19
{
161
19
  int top = lua_gettop(L);
162
19
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
163
19
  lua_insert(L, index);
164
19
  assert(lua_gettop(L) == top - 1 + 1);
165
19
}
166
167
/* int lua_isboolean(lua_State *L, int index); */
168
/* [-0, +0, -] */
169
static void
170
__lua_isboolean(lua_State *L, FuzzedDataProvider *fdp)
171
23
{
172
23
  int top = lua_gettop(L);
173
23
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
174
23
  int rc = lua_isboolean(L, index);
175
23
  assert(rc == 0 || rc == 1);
176
23
}
177
178
/* int lua_iscfunction(lua_State *L, int index); */
179
/* [-0, +0, -] */
180
static void
181
__lua_iscfunction(lua_State *L, FuzzedDataProvider *fdp)
182
13
{
183
13
  int top = lua_gettop(L);
184
13
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
185
13
  int rc = lua_iscfunction(L, index);
186
13
  assert(rc == 0 || rc == 1);
187
13
}
188
189
/* int lua_isfunction(lua_State *L, int index); */
190
/* [-0, +0, -] */
191
static void
192
__lua_isfunction(lua_State *L, FuzzedDataProvider *fdp)
193
15
{
194
15
  int top = lua_gettop(L);
195
15
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
196
15
  int rc = lua_isfunction(L, index);
197
15
  assert(rc == 0 || rc == 1);
198
15
}
199
200
/* int lua_isnil(lua_State *L, int index); */
201
/* [-0, +0, -] */
202
static void
203
__lua_isnil(lua_State *L, FuzzedDataProvider *fdp)
204
19
{
205
19
  int top = lua_gettop(L);
206
19
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
207
19
  int rc = lua_isnil(L, index);
208
19
  assert(rc == 0 || rc == 1);
209
19
}
210
211
/* int lua_isnone(lua_State *L, int index); */
212
/* [-0, +0, -] */
213
static void
214
__lua_isnone(lua_State *L, FuzzedDataProvider *fdp)
215
12
{
216
12
  int top = lua_gettop(L);
217
12
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
218
12
  int rc = lua_isnone(L, index);
219
12
  assert(rc == 0 || rc == 1);
220
12
  assert(lua_gettop(L) == top);
221
12
}
222
223
/* int lua_isnoneornil(lua_State *L, int index); */
224
/* [-0, +0, -] */
225
static void
226
__lua_isnoneornil(lua_State *L, FuzzedDataProvider *fdp)
227
20
{
228
20
  int top = lua_gettop(L);
229
20
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
230
20
  lua_isnoneornil(L, index);
231
20
  assert(lua_gettop(L) == top);
232
20
}
233
234
/* int lua_isstring(lua_State *L, int index); */
235
/* [-0, +0, -] */
236
static void
237
__lua_isstring(lua_State *L, FuzzedDataProvider *fdp)
238
12
{
239
12
  int top = lua_gettop(L);
240
12
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
241
12
  int rc = lua_isstring(L, index);
242
12
  assert(rc == 0 || rc == 1);
243
12
}
244
245
/* int lua_istable(lua_State *L, int index); */
246
/* [-0, +0, -] */
247
static void
248
__lua_istable(lua_State *L, FuzzedDataProvider *fdp)
249
4
{
250
4
  int top = lua_gettop(L);
251
4
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
252
4
  int rc = lua_istable(L, index);
253
4
  assert(rc == 0 || rc == 1);
254
4
}
255
256
/* void lua_pushinteger(lua_State *L, lua_Integer n); */
257
/* [-0, +1, -] */
258
static void
259
__lua_pushinteger(lua_State *L, FuzzedDataProvider *fdp)
260
201
{
261
201
  int top = lua_gettop(L);
262
201
  uint8_t n = fdp->ConsumeIntegral<uint8_t>();
263
201
  lua_pushinteger(L, n);
264
201
  assert(lua_gettop(L) == top + 1);
265
201
}
266
267
/* void lua_pushlstring(lua_State *L, const char *s, size_t len); */
268
/* [-0, +1, m] */
269
static void
270
__lua_pushlstring(lua_State *L, FuzzedDataProvider *fdp)
271
137
{
272
137
  int top = lua_gettop(L);
273
137
  auto str = fdp->ConsumeRandomLengthString(max_str_len);
274
137
  lua_pushlstring(L, str.c_str(), str.size());
275
137
  assert(lua_gettop(L) == top + 1);
276
137
}
277
278
/* void lua_pushnil(lua_State *L); */
279
/* [-0, +1, -] */
280
static void
281
__lua_pushnil(lua_State *L, FuzzedDataProvider *fdp)
282
644
{
283
644
  int top = lua_gettop(L);
284
644
  lua_pushnil(L);
285
644
  assert(lua_gettop(L) == top + 1);
286
644
}
287
288
/* void lua_pushnumber(lua_State *L, lua_Number n); */
289
/* [-0, +1, -] */
290
static void
291
__lua_pushnumber(lua_State *L, FuzzedDataProvider *fdp)
292
274
{
293
274
  int top = lua_gettop(L);
294
274
  uint8_t n = fdp->ConsumeIntegral<uint8_t>();
295
274
  lua_pushnumber(L, n);
296
274
  assert(lua_gettop(L) == top + 1);
297
274
}
298
299
/* void lua_pushvalue(lua_State *L, int index); */
300
/* [-0, +1, -] */
301
static void
302
__lua_pushvalue(lua_State *L, FuzzedDataProvider *fdp)
303
6
{
304
6
  int top = lua_gettop(L);
305
6
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
306
6
  lua_pushvalue(L, index);
307
6
  assert(lua_gettop(L) == top + 1);
308
6
}
309
310
/* void lua_remove(lua_State *L, int index); */
311
/* [-1, +0, -] */
312
static void
313
__lua_remove(lua_State *L, FuzzedDataProvider *fdp)
314
23
{
315
23
  int top = lua_gettop(L);
316
23
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
317
23
  lua_remove(L, index);
318
23
  assert(lua_gettop(L) == top - 1);
319
23
}
320
321
/* void lua_replace(lua_State *L, int index); */
322
/* [-1, +0, -] */
323
static void
324
__lua_replace(lua_State *L, FuzzedDataProvider *fdp)
325
23
{
326
23
  int top = lua_gettop(L);
327
23
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
328
23
  lua_replace(L, index);
329
23
  assert(lua_gettop(L) == top - 1);
330
23
}
331
332
/* void lua_setglobal(lua_State *L, const char *name); */
333
/* [-1, +0, e] */
334
static void
335
__lua_setglobal(lua_State *L, FuzzedDataProvider *fdp)
336
4
{
337
4
  int top = lua_gettop(L);
338
4
  auto str = fdp->ConsumeRandomLengthString(max_str_len);
339
4
  lua_setglobal(L, str.c_str());
340
4
  assert(lua_gettop(L) == top - 1);
341
4
}
342
343
/* void lua_settop(lua_State *L, int index); */
344
/* [-?, +?, -] */
345
static void
346
__lua_settop(lua_State *L, FuzzedDataProvider *fdp)
347
8
{
348
8
  int top = lua_gettop(L);
349
8
  int grow_slots = 2;
350
8
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top + grow_slots);
351
8
  lua_settop(L, index);
352
8
  assert(lua_gettop(L) == index);
353
8
}
354
355
/* int lua_status(lua_State *L); */
356
/* [-0, +0, -] */
357
static void
358
__lua_status(lua_State *L, FuzzedDataProvider *fdp)
359
4
{
360
4
  int rc = lua_status(L);
361
4
  assert(rc == 0 || rc == LUA_YIELD);
362
4
}
363
364
/* int lua_toboolean(lua_State *L, int index); */
365
/* [-0, +0, -] */
366
static void
367
__lua_toboolean(lua_State *L, FuzzedDataProvider *fdp)
368
11
{
369
11
  int top = lua_gettop(L);
370
11
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
371
11
  int rc = lua_toboolean(L, index);
372
11
  assert(rc == 0 || rc == 1);
373
11
}
374
375
/* lua_Integer lua_tointeger(lua_State *L, int index); */
376
/* [-0, +0, -] */
377
static void
378
__lua_tointeger(lua_State *L, FuzzedDataProvider *fdp)
379
6
{
380
6
  int top = lua_gettop(L);
381
6
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
382
6
  lua_tointeger(L, index);
383
6
  assert(lua_gettop(L) == top);
384
6
}
385
386
/* lua_Integer lua_tointegerx(lua_State *L, int index, int *isnum); */
387
/* [-0, +0, –] */
388
static void
389
__lua_tointegerx(lua_State *L, FuzzedDataProvider *fdp)
390
10
{
391
10
  int top = lua_gettop(L);
392
10
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
393
10
  int isnum;
394
10
  lua_tointegerx(L, index, &isnum);
395
10
  assert(isnum == 0 || isnum == 1);
396
10
  assert(lua_gettop(L) == top);
397
10
}
398
399
/* const char *lua_tolstring(lua_State *L, int index, size_t *len); */
400
/* [-0, +0, m] */
401
static void
402
__lua_tolstring(lua_State *L, FuzzedDataProvider *fdp)
403
26
{
404
26
  int top = lua_gettop(L);
405
26
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
406
26
  lua_tolstring(L, index, NULL);
407
26
  assert(lua_gettop(L) == top);
408
26
}
409
410
/* const char *lua_tostring(lua_State *L, int index); */
411
/* [-0, +0, m] */
412
static void
413
__lua_tostring(lua_State *L, FuzzedDataProvider *fdp)
414
10
{
415
10
  int top = lua_gettop(L);
416
10
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
417
10
  lua_tostring(L, index);
418
10
  assert(lua_gettop(L) == top);
419
10
}
420
421
/* int lua_type(lua_State *L, int index); */
422
/* [-0, +0, -] */
423
static void
424
__lua_type(lua_State *L, FuzzedDataProvider *fdp)
425
24
{
426
24
  int top = lua_gettop(L);
427
24
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
428
24
  int type = lua_type(L, index);
429
24
  assert(type == LUA_TBOOLEAN       ||
430
24
         type == LUA_TFUNCTION      ||
431
24
         type == LUA_TLIGHTUSERDATA ||
432
24
         type == LUA_TNIL           ||
433
24
         type == LUA_TNUMBER        ||
434
24
         type == LUA_TSTRING        ||
435
24
         type == LUA_TTABLE         ||
436
24
         type == LUA_TTHREAD        ||
437
24
         type == LUA_TUSERDATA      ||
438
24
         type == LUA_TNONE);
439
24
  assert(lua_gettop(L) == top);
440
24
}
441
442
/* void lua_getglobal(lua_State *L, const char *name); */
443
/* [-0, +1, e] */
444
static void
445
__lua_getglobal(lua_State *L, FuzzedDataProvider *fdp)
446
2
{
447
2
  auto name = fdp->ConsumeRandomLengthString(max_str_len);
448
2
  int top = lua_gettop(L);
449
2
  lua_getglobal(L, name.c_str());
450
2
  assert(lua_gettop(L) == top + 1);
451
2
}
452
453
/* const char *lua_setupvalue(lua_State *L, int funcindex, int n); */
454
/* [-(0|1), +0, –] */
455
static void
456
__lua_setupvalue(lua_State *L, FuzzedDataProvider *fdp)
457
23
{
458
23
  int top = lua_gettop(L);
459
23
  int funcindex = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
460
23
  int n = fdp->ConsumeIntegral<uint8_t>();
461
23
  lua_setupvalue(L, funcindex, n);
462
23
  assert(lua_gettop(L) == top);
463
23
}
464
465
/* const char *lua_getupvalue(lua_State *L, int funcindex, int n); */
466
/* [-0, +(0|1), –] */
467
static void
468
__lua_getupvalue(lua_State *L, FuzzedDataProvider *fdp)
469
25
{
470
25
  int top = lua_gettop(L);
471
25
  int funcindex = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
472
25
  int n = fdp->ConsumeIntegral<uint8_t>();
473
25
  lua_getupvalue(L, funcindex, n);
474
25
  assert(lua_gettop(L) == top || lua_gettop(L) == top + 1);
475
25
}
476
477
/* void *lua_touserdata(lua_State *L, int index); */
478
/* [-0, +0, -] */
479
static void
480
__lua_touserdata(lua_State *L, FuzzedDataProvider *fdp)
481
8
{
482
8
  int top = lua_gettop(L);
483
8
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
484
8
  lua_touserdata(L, index);
485
8
  assert(lua_gettop(L) == top);
486
8
}
487
488
/* int lua_islightuserdata(lua_State *L, int index); */
489
/* [-0, +0, -] */
490
static void
491
__lua_islightuserdata(lua_State *L, FuzzedDataProvider *fdp)
492
14
{
493
14
  int top = lua_gettop(L);
494
14
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
495
14
  int rc = lua_islightuserdata(L, index);
496
14
  assert(rc == 0 || rc == 1);
497
14
}
498
499
/* int lua_isuserdata(lua_State *L, int index); */
500
/* [-0, +0, -] */
501
static void
502
__lua_isuserdata(lua_State *L, FuzzedDataProvider *fdp)
503
24
{
504
24
  int top = lua_gettop(L);
505
24
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
506
24
  int rc = lua_isuserdata(L, index);
507
24
  assert(rc == 0 || rc == 1);
508
24
}
509
510
/* int lua_isthread(lua_State *L, int index); */
511
/* [-0, +0, -] */
512
static void
513
__lua_isthread(lua_State *L, FuzzedDataProvider *fdp)
514
14
{
515
14
  int top = lua_gettop(L);
516
14
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
517
14
  int rc = lua_isthread(L, index);
518
14
  assert(rc == 0 || rc == 1);
519
14
}
520
521
/* int lua_pushthread(lua_State *L); */
522
/* [-0, +1, -] */
523
static void
524
__lua_pushthread(lua_State *L, FuzzedDataProvider *fdp)
525
3
{
526
3
  int top = lua_gettop(L);
527
3
  int rc = lua_pushthread(L);
528
3
  assert(rc == 1);
529
3
  assert(lua_gettop(L) == top + 1);
530
3
}
531
532
/* int lua_next(lua_State *L, int index); */
533
/* [-1, +(2|0), e] */
534
static void
535
__lua_next(lua_State *L, FuzzedDataProvider *fdp)
536
17
{
537
17
  int top = lua_gettop(L);
538
17
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
539
17
  if (!lua_istable(L, index))
540
8
    return;
541
9
  lua_pushnil(L);  /* first key */
542
9
  lua_next(L, index);
543
9
  assert(lua_gettop(L) - top - 1 <= 2);
544
9
}
545
546
/* int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar); */
547
/* [-(0|1), +(0|1|2), m] */
548
static void
549
__lua_getinfo(lua_State *L, FuzzedDataProvider *fdp)
550
1
{
551
1
  int top = lua_gettop(L);
552
1
  lua_Debug ar;
553
1
  lua_pushcfunction(L, cfunction);
554
1
  const char *what = ">nSltufLr";
555
1
  lua_getinfo(L, what, &ar);
556
1
  assert(lua_gettop(L) >= top - 1 &&
557
1
         lua_gettop(L) <= top + 2);
558
1
}
559
560
/* int lua_getstack(lua_State *L, int level, lua_Debug *ar); */
561
/* [-0, +0, –] */
562
static void
563
__lua_getstack(lua_State *L, FuzzedDataProvider *fdp)
564
38
{
565
38
  int top = lua_gettop(L);
566
38
  int level = fdp->ConsumeIntegral<int8_t>();
567
38
  lua_Debug ar;
568
38
  lua_getstack(L, level, &ar);
569
38
  assert(lua_gettop(L) == top);
570
38
}
571
572
/* void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n); */
573
/* [-n, +1, m] */
574
static void
575
__lua_pushcclosure(lua_State *L, FuzzedDataProvider *fdp)
576
37
{
577
  /* Maximum n is 255 in lua_pushcclosure(3). */
578
37
  int n = fdp->ConsumeIntegralInRange<uint8_t>(1, 10);
579
159
  for (int i = 1; i < n; i++)
580
122
    lua_pushnumber(L, i);
581
37
  lua_pushcclosure(L, cfunction, n);
582
37
}
583
584
/* void lua_pushcfunction(lua_State *L, lua_CFunction f); */
585
/* [-0, +1, m] */
586
static void
587
__lua_pushcfunction(lua_State *L, FuzzedDataProvider *fdp)
588
975
{
589
975
  (void)fdp;
590
975
  int top = lua_gettop(L);
591
975
  lua_pushcfunction(L, cfunction);
592
975
  assert(lua_gettop(L) == top + 1);
593
975
}
594
595
/* int lua_getmetatable(lua_State *L, int index); */
596
/* [-0, +(0|1), -] */
597
static void
598
__lua_getmetatable(lua_State *L, FuzzedDataProvider *fdp)
599
14
{
600
14
  int top = lua_gettop(L);
601
14
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
602
14
  lua_getmetatable(L, index);
603
14
  assert(lua_gettop(L) - top <= 1);
604
14
}
605
606
/* void lua_newtable(lua_State *L); */
607
/* [-0, +1, m] */
608
static void
609
__lua_newtable(lua_State *L, FuzzedDataProvider *fdp)
610
1.54k
{
611
1.54k
  int top = lua_gettop(L);
612
1.54k
  lua_newtable(L);
613
1.54k
  assert(lua_gettop(L) == top + 1);
614
1.54k
}
615
616
/* lua_State *lua_newthread(lua_State *L); */
617
/* [-0, +1, m] */
618
static void
619
__lua_newthread(lua_State *L, FuzzedDataProvider *fdp)
620
803
{
621
803
  int top = lua_gettop(L);
622
803
  lua_newthread(L);
623
803
  assert(lua_gettop(L) == top + 1);
624
803
}
625
626
/* const char *lua_typename(lua_State *L, int tp); */
627
/* [-0, +0, -] */
628
static void
629
__lua_typename(lua_State *L, FuzzedDataProvider *fdp)
630
20
{
631
20
  int top = lua_gettop(L);
632
20
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
633
20
  const char* name = lua_typename(L, index);
634
20
  assert(name);
635
20
  assert(lua_gettop(L) == top);
636
20
}
637
638
static int gc_mode[] = {
639
  LUA_GCCOLLECT,
640
  LUA_GCCOUNT,
641
  LUA_GCCOUNTB,
642
  LUA_GCRESTART,
643
#if LUA_VERSION_NUM < 504
644
  LUA_GCSETPAUSE,
645
  LUA_GCSETSTEPMUL,
646
#endif /* LUA_VERSION_NUM */
647
  LUA_GCSTEP,
648
  LUA_GCSTOP,
649
#if LUA_VERSION_NUM > 501
650
  LUA_GCISRUNNING,
651
#elif LUA_VERSION_NUM > 503
652
  LUA_GCGEN,
653
  LUA_GCINC,
654
#endif /* LUA_VERSION_NUM */
655
};
656
657
/* int lua_gc(lua_State *L, int what, int data); */
658
/* [-0, +0, e] */
659
static void
660
__lua_gc(lua_State *L, FuzzedDataProvider *fdp)
661
2.27k
{
662
2.27k
  int top = lua_gettop(L);
663
2.27k
  uint8_t idx = fdp->ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(gc_mode) - 1);
664
2.27k
#if LUA_VERSION_NUM > 503
665
2.27k
  if (gc_mode[idx] == LUA_GCGEN) {
666
0
    uint8_t minor_mul = fdp->ConsumeIntegral<uint8_t>();
667
0
    uint8_t major_mul = fdp->ConsumeIntegral<uint8_t>();
668
0
    lua_gc(L, LUA_GCGEN, minor_mul, major_mul);
669
2.27k
  } else if (gc_mode[idx] == LUA_GCINC) {
670
0
    uint8_t pause = fdp->ConsumeIntegral<uint8_t>();
671
0
    uint8_t step_mul = fdp->ConsumeIntegral<uint8_t>();
672
0
    uint8_t step_size = fdp->ConsumeIntegral<uint8_t>();
673
0
    lua_gc(L, LUA_GCINC, pause, step_mul, step_size);
674
0
  } else
675
2.27k
    lua_gc(L, gc_mode[idx], 0);
676
#else
677
  lua_gc(L, gc_mode[idx], 0);
678
#endif /* LUA_VERSION_NUM */
679
2.27k
  assert(lua_gettop(L) == top);
680
2.27k
}
681
682
static int hook_mode[] = {
683
  0, /* Additional branch in Lua. */
684
  LUA_MASKCALL,
685
  LUA_MASKCOUNT,
686
  LUA_MASKLINE,
687
  LUA_MASKRET,
688
};
689
690
static void
691
Hook(lua_State *L, lua_Debug *ar)
692
8
{
693
8
  (void)L;
694
8
  (void)ar;
695
8
}
696
697
/* int lua_sethook(lua_State *L, lua_Hook f, int mask, int count); */
698
/* [-0, +0, -] */
699
static void
700
__lua_sethook(lua_State *L, FuzzedDataProvider *fdp)
701
2.25k
{
702
2.25k
  int top = lua_gettop(L);
703
2.25k
  uint8_t idx = fdp->ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(hook_mode) - 1);
704
2.25k
  lua_sethook(L, Hook, hook_mode[idx], 1);
705
2.25k
  assert(lua_gettop(L) == top);
706
2.25k
}
707
708
/* lua_Hook lua_gethook(lua_State *L); */
709
/* [-0, +0, –] */
710
static void
711
__lua_gethook(lua_State *L, FuzzedDataProvider *fdp)
712
3
{
713
3
  int top = lua_gettop(L);
714
3
  lua_gethook(L);
715
3
  assert(lua_gettop(L) == top);
716
3
}
717
718
/* int lua_gethookcount(lua_State *L); */
719
/* [-0, +0, –] */
720
static void
721
__lua_gethookcount(lua_State *L, FuzzedDataProvider *fdp)
722
3
{
723
3
  int top = lua_gettop(L);
724
3
  int hook_count = lua_gethookcount(L);
725
3
  assert(hook_count >= 0);
726
3
  assert(lua_gettop(L) == top);
727
3
}
728
729
/* int lua_gethookmask(lua_State *L); */
730
/* [-0, +0, –] */
731
static void
732
__lua_gethookmask(lua_State *L, FuzzedDataProvider *fdp)
733
3
{
734
3
  int top = lua_gettop(L);
735
3
  int hook_mask = lua_gethookmask(L);
736
3
  assert(hook_mask >= 0);
737
3
  assert(lua_gettop(L) == top);
738
3
}
739
740
/* void lua_rawget(lua_State *L, int index); */
741
/* [-1, +1, -] */
742
static void
743
__lua_rawget(lua_State *L, FuzzedDataProvider *fdp)
744
17
{
745
17
  int top = lua_gettop(L);
746
17
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
747
17
  if (!lua_istable(L, index))
748
4
    return;
749
13
  uint8_t key = fdp->ConsumeIntegral<uint8_t>();
750
13
  lua_pushnumber(L, key);
751
13
  top = lua_gettop(L);
752
13
  lua_rawget(L, index);
753
13
  assert(lua_gettop(L) == top);
754
13
}
755
756
/* void lua_rawset(lua_State *L, int index); */
757
/* [-2, +0, m] */
758
static void
759
__lua_rawset(lua_State *L, FuzzedDataProvider *fdp)
760
40
{
761
40
  int top = lua_gettop(L);
762
40
  if (top == 0)
763
0
    return;
764
40
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
765
40
  if (!lua_istable(L, index))
766
6
    return;
767
34
  uint8_t key = fdp->ConsumeIntegral<uint8_t>();
768
34
  uint8_t value = fdp->ConsumeIntegral<uint8_t>();
769
34
  lua_pushnumber(L, value);
770
34
  lua_pushnumber(L, key);
771
34
  top = lua_gettop(L);
772
34
  lua_rawset(L, index);
773
34
  assert(lua_gettop(L) == top - 2);
774
34
}
775
776
/* void lua_rawseti(lua_State *L, int index, lua_Integer i); */
777
/* [-1, +0, m] */
778
static void
779
__lua_rawseti(lua_State *L, FuzzedDataProvider *fdp)
780
42
{
781
42
  int top = lua_gettop(L);
782
42
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
783
42
  if (!lua_istable(L, index))
784
11
    return;
785
31
  int n = fdp->ConsumeIntegral<uint8_t>();
786
31
  __lua_pushnumber(L, fdp);
787
31
  top = lua_gettop(L);
788
31
  lua_rawseti(L, index, n);
789
31
  assert(lua_gettop(L) == top - 1);
790
31
}
791
792
/* int lua_rawgeti(lua_State *L, int index, lua_Integer n); */
793
/* [-0, +1, –] */
794
static void
795
__lua_rawgeti(lua_State *L, FuzzedDataProvider *fdp)
796
34
{
797
34
  int top = lua_gettop(L);
798
34
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
799
34
  if (!lua_istable(L, index))
800
9
    return;
801
25
  int i = fdp->ConsumeIntegral<uint8_t>();
802
25
  lua_rawgeti(L, index, i);
803
25
  assert(lua_gettop(L) == top + 1);
804
25
}
805
806
/* int lua_equal(lua_State *L, int index1, int index2); */
807
/* [-0, +0, e] */
808
#if LUA_VERSION_NUM == 501
809
static void
810
__lua_equal(lua_State *L, FuzzedDataProvider *fdp)
811
{
812
  int top = lua_gettop(L);
813
  if (top < 2)
814
    return;
815
  uint8_t index1 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
816
  uint8_t index2 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
817
  lua_equal(L, index1, index2);
818
  assert(lua_gettop(L) == top);
819
}
820
#endif /* LUA_VERSION_NUM */
821
822
/* int lua_lessthan(lua_State *L, int index1, int index2); */
823
/* [-0, +0, e] */
824
#if LUA_VERSION_NUM == 501
825
static void
826
__lua_lessthan(lua_State *L, FuzzedDataProvider *fdp)
827
{
828
  int top = lua_gettop(L);
829
  uint8_t index1 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
830
  int type1 = lua_type(L, index1);
831
  switch (type1) {
832
  case LUA_TNUMBER:
833
    __lua_pushnumber(L, fdp);
834
    break;
835
  case LUA_TSTRING:
836
    __lua_pushstring(L, fdp);
837
    break;
838
  default:
839
    return;
840
  }
841
  int rc = lua_lessthan(L, index1, -1);
842
  assert(rc == 0 || rc == 1);
843
}
844
#endif /* LUA_VERSION_NUM */
845
846
/* size_t lua_objlen(lua_State *L, int index); */
847
/* [-0, +0, -] */
848
#if LUA_VERSION_NUM < 503
849
static void
850
__lua_objlen(lua_State *L, FuzzedDataProvider *fdp)
851
{
852
  int top = lua_gettop(L);
853
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
854
#if LUA_VERSION_NUM == 501
855
  lua_objlen(L, index);
856
#else
857
  lua_rawlen(L, index);
858
#endif /* LUA_VERSION_NUM */
859
  assert(lua_gettop(L) == top);
860
}
861
#endif /* LUA_VERSION_NUM */
862
863
#if LUA_VERSION_NUM > 501
864
static int cmp_op[] = {
865
  LUA_OPEQ,
866
  LUA_OPLE,
867
  LUA_OPLT,
868
};
869
#endif /* LUA_VERSION_NUM */
870
871
/* int lua_compare(lua_State *L, int index1, int index2, int op); */
872
/* [-0, +0, e] */
873
#if LUA_VERSION_NUM > 501
874
static void
875
__lua_compare(lua_State *L, FuzzedDataProvider *fdp)
876
113
{
877
113
  int top = lua_gettop(L);
878
113
  uint8_t index1 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
879
113
  uint8_t index2 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
880
113
  if ((lua_type(L, index1) != LUA_TNUMBER) ||
881
113
      (lua_type(L, index2) != LUA_TNUMBER))
882
36
    return;
883
77
  int op_idx = fdp->ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(cmp_op) - 1);
884
77
  int rc = lua_compare(L, index1, index2, cmp_op[op_idx]);
885
77
  assert(rc == 0 || rc == 1);
886
77
  assert(lua_gettop(L) == top);
887
77
}
888
#endif /* LUA_VERSION_NUM */
889
890
/* size_t lua_rawlen(lua_State *L, int index); */
891
/* [-0, +0, –] */
892
#if LUA_VERSION_NUM > 501
893
static void
894
__lua_rawlen(lua_State *L, FuzzedDataProvider *fdp)
895
6
{
896
6
  int top = lua_gettop(L);
897
6
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
898
6
  lua_rawlen(L, index);
899
6
  assert(lua_gettop(L) == top);
900
6
}
901
#endif /* LUA_VERSION_NUM */
902
903
/* void lua_getfenv(lua_State *L, int index); */
904
/* [-0, +1, -] */
905
#if LUA_VERSION_NUM == 501
906
static void
907
__lua_getfenv(lua_State *L, FuzzedDataProvider *fdp)
908
{
909
  int top = lua_gettop(L);
910
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
911
  lua_getfenv(L, index);
912
  assert(lua_gettop(L) == top + 1);
913
}
914
#endif /* LUA_VERSION_NUM */
915
916
/* int lua_setfenv(lua_State *L, int index); */
917
/* [-1, +0, -] */
918
#if LUA_VERSION_NUM == 501
919
static void
920
__lua_setfenv(lua_State *L, FuzzedDataProvider *fdp)
921
{
922
  int top = lua_gettop(L);
923
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
924
  if (!lua_istable(L, -1))
925
    return;
926
  lua_setfenv(L, index);
927
  assert(lua_gettop(L) == top - 1);
928
}
929
#endif /* LUA_VERSION_NUM */
930
931
/* int lua_absindex(lua_State *L, int idx); */
932
/* [-0, +0, –] */
933
#if LUA_VERSION_NUM > 501
934
static void
935
__lua_absindex(lua_State *L, FuzzedDataProvider *fdp)
936
21
{
937
21
  int top = lua_gettop(L);
938
  /*
939
   * One can refer to any element in the stack by using an index:
940
   * A positive index represents an absolute stack position
941
   * (starting at 1); a negative index represents an offset
942
   * relative to the top of the stack.
943
   */
944
21
  int8_t index = fdp->ConsumeIntegralInRange<int8_t>(-top, top);
945
21
  int idx = lua_absindex(L, index);
946
21
  assert(idx > 0);
947
21
  assert(lua_gettop(L) == top);
948
21
}
949
#endif /* LUA_VERSION_NUM */
950
951
#if LUA_VERSION_NUM > 501
952
static int arith_op[] = {
953
  LUA_OPADD,
954
  LUA_OPSUB,
955
  LUA_OPMUL,
956
  LUA_OPDIV,
957
  LUA_OPMOD,
958
  LUA_OPPOW,
959
  LUA_OPUNM,
960
#if LUA_VERSION_NUM > 502
961
  LUA_OPBNOT,
962
  LUA_OPBAND,
963
  LUA_OPBOR,
964
  LUA_OPBXOR,
965
  LUA_OPSHL,
966
  LUA_OPSHR,
967
#endif /* LUA_VERSION_NUM */
968
};
969
#endif /* LUA_VERSION_NUM */
970
971
/* void lua_arith(lua_State *L, int op); */
972
/* [-(2|1), +1, e] */
973
#if LUA_VERSION_NUM > 501
974
static void
975
__lua_arith(lua_State *L, FuzzedDataProvider *fdp)
976
1
{
977
1
  int top = lua_gettop(L);
978
1
  if ((lua_type(L, 1) != LUA_TNUMBER) ||
979
1
      (lua_type(L, 2) != LUA_TNUMBER))
980
1
    return;
981
0
  int op_idx = fdp->ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(arith_op) - 1);
982
0
  int op = arith_op[op_idx];
983
984
  /* Handle division by zero. */
985
0
  lua_pushnumber(L, 0);
986
0
  if ((op == LUA_OPMOD ||
987
0
       op == LUA_OPDIV) && lua_rawequal(L, 2, -1))
988
0
    return;
989
0
  lua_pop(L, 1);
990
991
0
  lua_arith(L, op);
992
0
  assert(lua_gettop(L) <= top - 1 + 1);
993
0
}
994
#endif /* LUA_VERSION_NUM */
995
996
/* void lua_setmetatable(lua_State *L, int index); */
997
/* [-1, +0, –] */
998
static void
999
__lua_setmetatable(lua_State *L, FuzzedDataProvider *fdp)
1000
15
{
1001
15
  luaL_getmetatable(L, TYPE_NAME_TORTURE);
1002
15
  int top = lua_gettop(L);
1003
15
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1004
15
  lua_setmetatable(L, index);
1005
15
  assert(lua_gettop(L) == top - 1);
1006
15
}
1007
1008
/* void luaL_setmetatable(lua_State *L, const char *tname); */
1009
/* [-0, +0, –] */
1010
static void
1011
__luaL_setmetatable(lua_State *L, FuzzedDataProvider *fdp)
1012
9
{
1013
9
  int top = lua_gettop(L);
1014
9
  luaL_setmetatable(L, TYPE_NAME_TORTURE);
1015
9
  assert(lua_gettop(L) == top);
1016
9
}
1017
1018
/* int lua_isyieldable(lua_State *L); */
1019
/* [-0, +0, –] */
1020
#if LUA_VERSION_NUM > 502 || defined(LUAJIT)
1021
static void
1022
__lua_isyieldable(lua_State *L, FuzzedDataProvider *fdp)
1023
1
{
1024
1
  (void)fdp;
1025
1
  int rc = lua_isyieldable(L);
1026
1
  assert(rc == 0 || rc == 1);
1027
1
}
1028
#endif /* LUA_VERSION_NUM */
1029
1030
/* int lua_cpcall(lua_State *L, lua_CFunction func, void *ud); */
1031
/* [-0, +(0|1), -] */
1032
#if LUA_VERSION_NUM == 501
1033
static void
1034
__lua_cpcall(lua_State *L, FuzzedDataProvider *fdp)
1035
{
1036
  int top = lua_gettop(L);
1037
  int rc = lua_cpcall(L, cfunction, NULL);
1038
  assert(rc == 0);
1039
  assert(lua_gettop(L) - top <= 1);
1040
}
1041
#endif /* LUA_VERSION_NUM */
1042
1043
/* void lua_gettable(lua_State *L, int index); */
1044
/* [-1, +1, e] */
1045
static void
1046
__lua_gettable(lua_State *L, FuzzedDataProvider *fdp)
1047
43
{
1048
43
  int top = lua_gettop(L);
1049
43
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1050
43
  if (!lua_istable(L, index))
1051
4
    return;
1052
39
  uint8_t key = fdp->ConsumeIntegral<uint8_t>();
1053
39
  lua_pushnumber(L, key);
1054
39
  lua_gettable(L, index);
1055
39
  assert(lua_gettop(L) == top + 1);
1056
39
}
1057
1058
/* void lua_rotate(lua_State *L, int idx, int n); */
1059
/* [-0, +0, –] */
1060
#if LUA_VERSION_NUM > 502
1061
static void
1062
__lua_rotate(lua_State *L, FuzzedDataProvider *fdp)
1063
23
{
1064
23
  int top = lua_gettop(L);
1065
23
  int min_n = 1;
1066
23
  uint8_t idx = fdp->ConsumeIntegralInRange<uint8_t>(1, top - min_n);
1067
23
  uint8_t n = fdp->ConsumeIntegralInRange<uint8_t>(1, top - idx);
1068
23
  lua_rotate(L, idx, n);
1069
23
  assert(lua_gettop(L) == top);
1070
23
}
1071
#endif /* LUA_VERSION_NUM */
1072
1073
/* void lua_seti(lua_State *L, int index, lua_Integer n); */
1074
/* [-1, +0, e] */
1075
#if LUA_VERSION_NUM > 502
1076
static void
1077
__lua_seti(lua_State *L, FuzzedDataProvider *fdp)
1078
51
{
1079
51
  int top = lua_gettop(L);
1080
51
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1081
51
  if (!lua_istable(L, index))
1082
10
    return;
1083
41
  int n = fdp->ConsumeIntegral<uint8_t>();
1084
41
  __lua_pushnumber(L, fdp);
1085
41
  top = lua_gettop(L);
1086
41
  lua_seti(L, index, n);
1087
41
  assert(lua_gettop(L) == top - 1);
1088
41
}
1089
#endif /* LUA_VERSION_NUM */
1090
1091
/* int lua_geti(lua_State *L, int index, lua_Integer i); */
1092
/* [-0, +1, e] */
1093
#if LUA_VERSION_NUM > 502
1094
static void
1095
__lua_geti(lua_State *L, FuzzedDataProvider *fdp)
1096
52
{
1097
52
  int top = lua_gettop(L);
1098
52
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1099
52
  if (!lua_istable(L, index))
1100
4
    return;
1101
48
  int i = fdp->ConsumeIntegral<uint8_t>();
1102
48
  lua_geti(L, index, i);
1103
48
  assert(lua_gettop(L) == top + 1);
1104
48
}
1105
#endif /* LUA_VERSION_NUM */
1106
1107
/* void lua_getuservalue(lua_State *L, int index); */
1108
/* [-0, +1, –] */
1109
#if LUA_VERSION_NUM > 501 && LUA_VERSION_NUM < 504
1110
static void
1111
__lua_getuservalue(lua_State *L, FuzzedDataProvider *fdp)
1112
{
1113
  int top = lua_gettop(L);
1114
  int index = fdp->ConsumeIntegral<uint8_t>();
1115
  lua_getuservalue(L, index);
1116
  assert(lua_gettop(L) == top + 1);
1117
}
1118
#endif /* LUA_VERSION_NUM */
1119
1120
/* void lua_setuservalue(lua_State *L, int index); */
1121
/* [-1, +0, –] */
1122
#if LUA_VERSION_NUM > 501 && LUA_VERSION_NUM < 504
1123
static void
1124
__lua_setuservalue(lua_State *L, FuzzedDataProvider *fdp)
1125
{
1126
  int top = lua_gettop(L);
1127
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1128
  lua_setuservalue(L, index);
1129
  assert(lua_gettop(L) == top);
1130
}
1131
#endif /* LUA_VERSION_NUM */
1132
1133
/* void lua_xmove(lua_State *from, lua_State *to, int n); */
1134
/* [-?, +?, -] */
1135
static void
1136
__lua_xmove(lua_State *L, FuzzedDataProvider *fdp)
1137
18
{
1138
18
  lua_State *co1 = lua_newthread(L);
1139
18
  lua_State *co2 = lua_newthread(L);
1140
18
  __lua_pushnumber(co1, fdp);
1141
18
  lua_xmove(co1, co2, 1);
1142
18
  lua_settop(co1, 0);
1143
18
  lua_settop(co2, 0);
1144
18
}
1145
1146
/* void lua_register(lua_State *L, const char *name, lua_CFunction f); */
1147
/* [-0, +0, e] */
1148
static void
1149
__lua_register(lua_State *L, FuzzedDataProvider *fdp)
1150
10
{
1151
10
  int top = lua_gettop(L);
1152
10
  lua_register(L, "cfunction", cfunction);
1153
10
  assert(lua_gettop(L) == top);
1154
10
}
1155
1156
/**
1157
 * Lua 5.1: int lua_resume(lua_State *L, int narg);
1158
 * Lua 5.3: int lua_resume(lua_State *L, lua_State *from, int nargs);
1159
 * Lua 5.2: int lua_resume(lua_State *L, lua_State *from, int nargs);
1160
 * Lua 5.4: int lua_resume(lua_State *L, lua_State *from, int nargs, int *nresults);
1161
 * [-?, +?, -]
1162
 */
1163
static void
1164
__lua_resume(lua_State *L, FuzzedDataProvider *fdp)
1165
1
{
1166
1
  lua_State *co = lua_newthread(L);
1167
1
  lua_pushcfunction(co, cfunction);
1168
1
  int res = -1;
1169
#if LUA_VERSION_NUM == 501
1170
  res = lua_resume(L, 0);
1171
#elif LUA_VERSION_NUM == 503 || LUA_VERSION_NUM == 502
1172
  res = lua_resume(co, L, 0);
1173
#else
1174
1
  int nres;
1175
1
  res = lua_resume(co, L, 0, &nres);
1176
1
#endif /* LUA_VERSION_NUM */
1177
  /* assert(res == LUA_OK); */
1178
1
  (void)res;
1179
1
  lua_settop(co, 0);
1180
1
}
1181
1182
/* void lua_setfield(lua_State *L, int index, const char *k); */
1183
/* [-1, +0, e] */
1184
static void
1185
__lua_setfield(lua_State *L, FuzzedDataProvider *fdp)
1186
152
{
1187
152
  int top = lua_gettop(L);
1188
152
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1189
152
  if (lua_type(L, index) != LUA_TTABLE)
1190
5
    return;
1191
147
  auto k = fdp->ConsumeRemainingBytesAsString();
1192
147
  lua_setfield(L, index, k.c_str());
1193
147
  assert(lua_gettop(L) == top - 1);
1194
147
}
1195
1196
/* const void *lua_topointer(lua_State *L, int index); */
1197
/* [-0, +0, -] */
1198
static void
1199
__lua_topointer(lua_State *L, FuzzedDataProvider *fdp)
1200
13
{
1201
13
  int top = lua_gettop(L);
1202
13
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1203
13
  const void *p = lua_topointer(L, index);
1204
  /*
1205
   * The value can be a userdata, a table, a thread, or a function;
1206
   * otherwise, lua_topointer returns NULL.
1207
   */
1208
13
  int type = lua_type(L, index);
1209
13
  if (type == LUA_TUSERDATA  ||
1210
13
      type == LUA_TTHREAD    ||
1211
13
      type == LUA_TTABLE     ||
1212
13
#if LUA_VERSION_NUM > 503 || defined(LUAJIT)
1213
13
      type == LUA_TSTRING    ||
1214
13
#endif /* LUA_VERSION_NUM */
1215
13
      type == LUA_TFUNCTION)
1216
10
    assert(p);
1217
3
  else
1218
3
    assert(p == NULL);
1219
13
  assert(lua_gettop(L) == top);
1220
13
}
1221
1222
/* lua_CFunction lua_tocfunction(lua_State *L, int index); */
1223
/* [-0, +0, -] */
1224
static void
1225
__lua_tocfunction(lua_State *L, FuzzedDataProvider *fdp)
1226
21
{
1227
21
  int top = lua_gettop(L);
1228
21
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1229
21
  lua_tocfunction(L, index);
1230
21
  assert(lua_gettop(L) == top);
1231
21
}
1232
1233
/* void lua_settable(lua_State *L, int index); */
1234
/* [-2, +0, e] */
1235
static void
1236
__lua_settable(lua_State *L, FuzzedDataProvider *fdp)
1237
9
{
1238
9
  int top = lua_gettop(L);
1239
9
  lua_createtable(L, 0, 1);
1240
1241
9
  lua_pushstring(L, "language");
1242
9
  lua_pushstring(L, "Lua");
1243
9
  lua_settable(L, -3);
1244
1245
9
  assert(lua_gettop(L) == top + 1);
1246
9
}
1247
1248
/* void lua_getfield(lua_State *L, int index, const char *k); */
1249
/* [-0, +1, e] */
1250
static void
1251
__lua_getfield(lua_State *L, FuzzedDataProvider *fdp)
1252
215
{
1253
215
  int top = lua_gettop(L);
1254
215
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1255
215
  if (lua_type(L, index) != LUA_TTABLE)
1256
8
    return;
1257
207
  auto k = fdp->ConsumeRemainingBytesAsString();
1258
207
  lua_getfield(L, index, k.c_str());
1259
207
  assert(lua_gettop(L) == top + 1);
1260
207
}
1261
1262
/* void *lua_newuserdata(lua_State *L, size_t size); */
1263
/* [-0, +1, m] */
1264
static void
1265
__lua_newuserdata(lua_State *L, FuzzedDataProvider *fdp)
1266
36
{
1267
36
  uint8_t size = fdp->ConsumeIntegral<uint8_t>();
1268
36
  lua_newuserdata(L, size);
1269
36
}
1270
1271
/* const char *lua_pushfstring(lua_State *L, const char *fmt, ...); */
1272
/* [-0, +1, m] */
1273
static void
1274
__lua_pushfstring(lua_State *L, FuzzedDataProvider *fdp)
1275
15
{
1276
15
  int top = lua_gettop(L);
1277
15
  auto arg1 = fdp->ConsumeRandomLengthString(max_str_len);
1278
15
  auto arg2 = fdp->ConsumeRandomLengthString(max_str_len);
1279
15
  auto arg3 = fdp->ConsumeRandomLengthString(max_str_len);
1280
15
  auto arg4 = fdp->ConsumeRandomLengthString(max_str_len);
1281
15
  auto arg5 = fdp->ConsumeRandomLengthString(max_str_len);
1282
15
  char fmt_str[] = "%s %f %p %d %c";
1283
15
  lua_pushfstring(L, fmt_str, arg1.c_str(), arg2.c_str(),
1284
15
                              arg3.c_str(), arg4.c_str(),
1285
15
                              arg5.c_str());
1286
15
  assert(lua_gettop(L) == top + 1);
1287
15
}
1288
1289
/* lua_State *lua_tothread(lua_State *L, int index); */
1290
/* [-0, +0, -] */
1291
static void
1292
__lua_tothread(lua_State *L, FuzzedDataProvider *fdp)
1293
15
{
1294
15
  int top = lua_gettop(L);
1295
15
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1296
15
  lua_tothread(L, index);
1297
15
  assert(lua_gettop(L) == top);
1298
15
}
1299
1300
/* lua_Number luaL_checknumber(lua_State *L, int narg); */
1301
/* [-0, +0, v] */
1302
static void
1303
__luaL_checknumber(lua_State *L, FuzzedDataProvider *fdp)
1304
24
{
1305
24
  int top = lua_gettop(L);
1306
24
  uint8_t narg = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1307
  /*
1308
   * Functions called luaL_check* always raise an error
1309
   * if the check is not satisfied.
1310
   */
1311
24
  if (lua_type(L, narg) != LUA_TNUMBER)
1312
23
    return;
1313
1
  luaL_checknumber(L, narg);
1314
1
  assert(lua_gettop(L) == top);
1315
1
}
1316
1317
/* lua_Integer luaL_checkinteger(lua_State *L, int arg); */
1318
/* [-0, +0, v] */
1319
static void
1320
__luaL_checkinteger(lua_State *L, FuzzedDataProvider *fdp)
1321
13
{
1322
13
  int top = lua_gettop(L);
1323
13
  uint8_t arg = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1324
  /*
1325
   * Functions called luaL_check* always raise an error
1326
   * if the check is not satisfied.
1327
   */
1328
13
  if (lua_type(L, arg) != LUA_TNUMBER)
1329
11
    return;
1330
2
  luaL_checkinteger(L, arg);
1331
2
  assert(lua_gettop(L) == top);
1332
2
}
1333
1334
/* const char *luaL_checkstring(lua_State *L, int arg); */
1335
/* [-0, +0, v] */
1336
static void
1337
__luaL_checkstring(lua_State *L, FuzzedDataProvider *fdp)
1338
27
{
1339
27
  int top = lua_gettop(L);
1340
27
  uint8_t arg = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1341
  /*
1342
   * Functions called luaL_check* always raise an error
1343
   * if the check is not satisfied.
1344
   */
1345
27
  if (lua_type(L, arg) != LUA_TSTRING)
1346
24
    return;
1347
3
  luaL_checkstring(L, arg);
1348
3
  assert(lua_gettop(L) == top);
1349
3
}
1350
1351
/* void luaL_checktype(lua_State *L, int arg, int t); */
1352
/* [-0, +0, v] */
1353
static void
1354
__luaL_checktype(lua_State *L, FuzzedDataProvider *fdp)
1355
10
{
1356
10
  int top = lua_gettop(L);
1357
10
  uint8_t arg = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1358
  /*
1359
   * Functions called luaL_check* always raise an error
1360
   * if the check is not satisfied.
1361
   */
1362
10
  int type = lua_type(L, arg);
1363
10
  luaL_checktype(L, arg, type);
1364
10
  assert(lua_gettop(L) == top);
1365
10
}
1366
1367
/* void luaL_checkany(lua_State *L, int arg); */
1368
/* [-0, +0, v] */
1369
static void
1370
__luaL_checkany(lua_State *L, FuzzedDataProvider *fdp)
1371
9
{
1372
9
  int top = lua_gettop(L);
1373
9
  uint8_t arg = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1374
  /*
1375
   * Functions called luaL_check* always raise an error
1376
   * if the check is not satisfied.
1377
   */
1378
9
  luaL_checkany(L, arg);
1379
9
  assert(lua_gettop(L) == top);
1380
9
}
1381
1382
/* int lua_getiuservalue(lua_State *L, int index, int n); */
1383
/* [-0, +1, –] */
1384
#if LUA_VERSION_NUM > 503
1385
static void
1386
__lua_getiuservalue(lua_State *L, FuzzedDataProvider *fdp)
1387
21
{
1388
21
  lua_newuserdatauv(L, 1, 0);
1389
21
  __lua_pushnumber(L, fdp);
1390
21
  int n = 1;
1391
21
  lua_setiuservalue(L, -2, n);
1392
21
  int top = lua_gettop(L);
1393
21
  lua_getiuservalue(L, -1, n);
1394
21
  assert(lua_gettop(L) == top + 1);
1395
21
}
1396
#endif /* LUA_VERSION_NUM */
1397
1398
/* int lua_setiuservalue(lua_State *L, int index, int n); */
1399
/* [-1, +0, –] */
1400
#if LUA_VERSION_NUM > 503
1401
static void
1402
__lua_setiuservalue(lua_State *L, FuzzedDataProvider *fdp)
1403
18
{
1404
18
  __lua_newuserdata(L, fdp);
1405
18
  __lua_pushnumber(L, fdp);
1406
18
  uint8_t n = fdp->ConsumeIntegral<uint8_t>();
1407
18
  int top = lua_gettop(L);
1408
18
  lua_setiuservalue(L, -2, n);
1409
18
  assert(lua_gettop(L) == top - 1);
1410
18
}
1411
#endif /* LUA_VERSION_NUM */
1412
1413
/* void *lua_upvalueid(lua_State *L, int funcindex, int n); */
1414
/* [-0, +0, –] */
1415
static void
1416
__lua_upvalueid(lua_State *L, FuzzedDataProvider *fdp)
1417
4
{
1418
4
  int funcindex = -1;
1419
4
  lua_Debug ar;
1420
4
  lua_pushcfunction(L, cfunction);
1421
4
  int n = fdp->ConsumeIntegral<uint8_t>();
1422
4
  lua_setupvalue(L, funcindex, n);
1423
4
  assert(lua_getinfo(L, ">u", &ar) == 1);
1424
4
  if (ar.nups == 0)
1425
4
    return;
1426
0
  int top = lua_gettop(L);
1427
0
  void *p = lua_upvalueid(L, funcindex, n);
1428
0
  assert(p);
1429
0
  assert(lua_gettop(L) == top);
1430
0
}
1431
1432
/* int lua_rawequal(lua_State *L, int index1, int index2); */
1433
/* [-0, +0, –] */
1434
static void
1435
__lua_rawequal(lua_State *L, FuzzedDataProvider *fdp)
1436
38
{
1437
38
  int top = lua_gettop(L);
1438
38
  if (top < 2)
1439
0
    return;
1440
38
  uint8_t index1 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1441
38
  uint8_t index2 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1442
38
  lua_rawequal(L, index1, index2);
1443
38
  assert(lua_gettop(L) == top);
1444
38
}
1445
1446
/* void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level); */
1447
/* [-0, +1, m] */
1448
static void
1449
__luaL_traceback(lua_State *L, FuzzedDataProvider *fdp)
1450
8
{
1451
8
  int top = lua_gettop(L);
1452
8
  auto buf = fdp->ConsumeRandomLengthString(max_str_len);
1453
8
  luaL_traceback(L, L, buf.c_str(), 1);
1454
8
  assert(lua_gettop(L) == top + 1);
1455
8
}
1456
1457
/* const char *lua_tolstring(lua_State *L, int index, size_t *len); */
1458
/* [-0, +0, m] */
1459
/* const char *luaL_tolstring(lua_State *L, int idx, size_t *len); */
1460
/* [-0, +1, e] */
1461
static void
1462
__luaL_tolstring(lua_State *L, FuzzedDataProvider *fdp)
1463
38
{
1464
38
  int top = lua_gettop(L);
1465
38
  auto idx = fdp->ConsumeIntegralInRange(1, top);
1466
#if LUA_VERSION_NUM < 503
1467
  lua_tolstring(L, idx, NULL);
1468
  assert(lua_gettop(L) == top);
1469
#else
1470
38
  luaL_tolstring(L, idx, NULL);
1471
38
  assert(lua_gettop(L) == top + 1);
1472
38
#endif /* LUA_VERSION_NUM */
1473
38
}
1474
1475
/* void lua_copy(lua_State *L, int fromidx, int toidx); */
1476
/* [-0, +0, –] */
1477
#if LUA_VERSION_NUM > 501 || defined(LUAJIT)
1478
static void
1479
__lua_copy(lua_State *L, FuzzedDataProvider *fdp)
1480
8
{
1481
8
  int top = lua_gettop(L);
1482
8
  uint8_t fromidx = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1483
8
  uint8_t toidx = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1484
8
  if (fromidx == toidx)
1485
5
    return;
1486
3
  lua_copy(L, fromidx, toidx);
1487
3
  assert(lua_gettop(L) == top);
1488
3
}
1489
#endif /* LUA_VERSION_NUM */
1490
1491
/* void luaL_checkversion(lua_State *L); */
1492
/* [-0, +0, v] */
1493
#if LUA_VERSION_NUM > 501
1494
static void
1495
__luaL_checkversion(lua_State *L, FuzzedDataProvider *fdp)
1496
2
{
1497
2
  int top = lua_gettop(L);
1498
2
  luaL_checkversion(L);
1499
2
  assert(top == lua_gettop(L));
1500
2
}
1501
#endif /* LUA_VERSION_NUM */
1502
1503
/* size_t lua_stringtonumber(lua_State *L, const char *s); */
1504
/* [-0, +1, –] */
1505
#if LUA_VERSION_NUM > 502
1506
static void
1507
__lua_stringtonumber(lua_State *L, FuzzedDataProvider *fdp)
1508
22
{
1509
22
  int top = lua_gettop(L);
1510
22
  auto str = fdp->ConsumeRandomLengthString(max_str_len);
1511
22
  size_t sz = lua_stringtonumber(L, str.c_str());
1512
22
  if (sz == 0) {
1513
21
    assert(lua_gettop(L) == top);
1514
21
  } else {
1515
1
    assert(lua_gettop(L) == top + 1);
1516
1
    assert(lua_isnumber(L, -1) == 1);
1517
1
  }
1518
22
}
1519
#endif /* LUA_VERSION_NUM */
1520
1521
/* int lua_rawgetp(lua_State *L, int index, const void *p); */
1522
/* [-0, +1, –] */
1523
#if LUA_VERSION_NUM > 501
1524
static void
1525
__lua_rawgetp(lua_State *L, FuzzedDataProvider *fdp)
1526
24
{
1527
24
  int top = lua_gettop(L);
1528
24
  auto idx = fdp->ConsumeIntegralInRange(1, top);
1529
24
  if (lua_type(L, idx) != LUA_TTABLE)
1530
13
    return;
1531
11
  void *p = malloc(1);
1532
11
  lua_rawgetp(L, idx, p);
1533
11
  free(p);
1534
11
  assert(lua_gettop(L) == top + 1);
1535
11
}
1536
#endif /* LUA_VERSION_NUM */
1537
1538
/* void lua_len(lua_State *L, int index); */
1539
/* [-0, +1, e] */
1540
#if LUA_VERSION_NUM > 501
1541
static void
1542
__lua_len(lua_State *L, FuzzedDataProvider *fdp)
1543
28
{
1544
28
  int top = lua_gettop(L);
1545
28
  auto idx = fdp->ConsumeIntegralInRange(1, top);
1546
28
  if (lua_type(L, idx) != LUA_TTABLE &&
1547
28
      lua_type(L, idx) != LUA_TSTRING)
1548
9
    return;
1549
19
  lua_len(L, idx);
1550
19
  assert(lua_gettop(L) == top + 1);
1551
19
}
1552
#endif /* LUA_VERSION_NUM */
1553
1554
/* lua_Integer luaL_len(lua_State *L, int index); */
1555
/* [-0, +0, e] */
1556
#if LUA_VERSION_NUM > 501
1557
static void
1558
__luaL_len(lua_State *L, FuzzedDataProvider *fdp)
1559
17
{
1560
17
  int top = lua_gettop(L);
1561
17
  auto index = fdp->ConsumeIntegralInRange(1, top);
1562
17
  int type = lua_type(L, index);
1563
17
  if (type == LUA_TFUNCTION  ||
1564
17
      type == LUA_TTHREAD    ||
1565
17
      type == LUA_TNUMBER    ||
1566
17
      type == LUA_TBOOLEAN   ||
1567
17
      type == LUA_TNIL       ||
1568
17
      type == LUA_TUSERDATA)
1569
10
    return;
1570
7
  luaL_len(L, index);
1571
7
  assert(lua_gettop(L) == top);
1572
7
}
1573
#endif /* LUA_VERSION_NUM */
1574
1575
/* lua_Alloc lua_getallocf(lua_State *L, void **ud); */
1576
/* [-0, +0, –] */
1577
static void
1578
__lua_getallocf(lua_State *L, FuzzedDataProvider *fdp)
1579
3
{
1580
3
  int top = lua_gettop(L);
1581
3
  void *state;
1582
3
  lua_getallocf(L, &state);
1583
3
  assert(lua_gettop(L) == top);
1584
3
}
1585
1586
/* int luaL_ref(lua_State *L, int t); */
1587
/* [-1, +0, e] */
1588
static void
1589
__luaL_ref(lua_State *L, FuzzedDataProvider *fdp)
1590
27
{
1591
27
  int top = lua_gettop(L);
1592
27
  auto idx = fdp->ConsumeIntegralInRange(1, top);
1593
27
  if (lua_type(L, idx) != LUA_TTABLE)
1594
7
    return;
1595
20
  luaL_ref(L, idx);
1596
20
  assert(lua_gettop(L) == top - 1);
1597
20
}
1598
1599
/* void luaL_checkstack(lua_State *L, int sz, const char *msg); */
1600
/* [-0, +0, v] */
1601
static void
1602
__luaL_checkstack(lua_State *L, FuzzedDataProvider *fdp)
1603
1
{
1604
1
  int top = lua_gettop(L);
1605
1
  int sz = top + 1;
1606
1
  char err_msg[] = "shit happens";
1607
1
  luaL_checkstack(L, sz, err_msg);
1608
1
  assert(lua_gettop(L) == top);
1609
1
}
1610
1611
/* const lua_Number *lua_version(lua_State *L); */
1612
/* [-0, +0, v] */
1613
#if LUA_VERSION_NUM > 501 || defined(LUAJIT)
1614
static void
1615
__lua_version(lua_State *L, FuzzedDataProvider *fdp)
1616
1
{
1617
1
  int top = lua_gettop(L);
1618
#if LUA_VERSION_NUM < 504
1619
  const lua_Number *v = lua_version(L);
1620
  assert(v);
1621
#else
1622
1
  lua_Number v = lua_version(L);
1623
1
  assert(v != 0);
1624
1
#endif /* LUA_VERSION_NUM */
1625
1
  assert(lua_gettop(L) == top);
1626
1
}
1627
#endif /* LUA_VERSION_NUM */
1628
1629
/* int luaL_getmetafield(lua_State *L, int obj, const char *e); */
1630
/* [-0, +(0|1), e] */
1631
static void
1632
__luaL_getmetafield(lua_State *L, FuzzedDataProvider *fdp)
1633
30
{
1634
30
  int top = lua_gettop(L);
1635
30
  auto obj = fdp->ConsumeIntegralInRange(1, top);
1636
30
  const char e[] = "xxx";
1637
30
  luaL_getmetafield(L, obj, e);
1638
30
  assert(lua_gettop(L) == top || lua_gettop(L) == top + 1);
1639
30
}
1640
1641
/* void lua_call(lua_State *L, int nargs, int nresults); */
1642
/* [-(nargs+1), +nresults, e] */
1643
static void
1644
__lua_call(lua_State *L, FuzzedDataProvider *fdp)
1645
44
{
1646
44
  int top = lua_gettop(L);
1647
  /* Function to be called. */
1648
44
  lua_pushcfunction(L, cfunction);
1649
44
  int nargs = 0;
1650
44
  int nresults = 0;
1651
44
  lua_call(L, nargs, nresults);
1652
44
  assert(lua_gettop(L) == top + nresults - nargs);
1653
44
}
1654
1655
/* int lua_pcall(lua_State *L, int nargs, int nresults, int msgh); */
1656
/* [-(nargs + 1), +(nresults|1), –] */
1657
static void
1658
__lua_pcall(lua_State *L, FuzzedDataProvider *fdp)
1659
2
{
1660
2
  int top = lua_gettop(L);
1661
  /* Function to be called. */
1662
2
  lua_pushcfunction(L, cfunction);
1663
2
  int nargs = 0;
1664
2
  int nresults = 0;
1665
2
  int res = lua_pcall(L, nargs, nresults, 0);
1666
2
  assert(res == LUA_OK);
1667
2
  assert(lua_gettop(L) == top + nresults - nargs);
1668
2
}
1669
1670
/* int luaL_loadstring(lua_State *L, const char *s); */
1671
/* [-0, +1, m] */
1672
static void
1673
__luaL_loadstring(lua_State *L, FuzzedDataProvider *fdp)
1674
19
{
1675
19
  int top = lua_gettop(L);
1676
19
  int res = luaL_loadstring(L, "a = a + 1");
1677
19
  assert(res == LUA_OK);
1678
19
  assert(lua_gettop(L) == top + 1);
1679
19
}
1680
1681
/* int luaL_callmeta(lua_State *L, int obj, const char *e); */
1682
/* [-0, +(0|1), e] */
1683
static void
1684
__luaL_callmeta(lua_State *L, FuzzedDataProvider *fdp)
1685
23
{
1686
23
  int top = lua_gettop(L);
1687
23
  auto obj = fdp->ConsumeIntegralInRange(1, top);
1688
23
  luaL_callmeta(L, obj, MT_FUNC_NAME_TORTURE);
1689
23
  assert(lua_gettop(L) == top || lua_gettop(L) == top + 1);
1690
23
}
1691
1692
/* void luaL_where(lua_State *L, int lvl); */
1693
/* [-0, +1, m] */
1694
static void
1695
__luaL_where(lua_State *L, FuzzedDataProvider *fdp)
1696
6
{
1697
6
  int top = lua_gettop(L);
1698
6
  luaL_where(L, 1);
1699
6
  assert(lua_gettop(L) == top + 1);
1700
6
}
1701
1702
typedef void
1703
(*lua_func)(lua_State *L, FuzzedDataProvider *fdp);
1704
1705
static lua_func push_func[] = {
1706
  &__lua_newtable,
1707
  &__lua_newthread,
1708
  &__lua_pushboolean,
1709
  &__lua_pushcfunction,
1710
  &__lua_pushinteger,
1711
  &__lua_pushlstring,
1712
  &__lua_pushnil,
1713
  &__lua_pushnumber,
1714
  &__lua_pushstring,
1715
};
1716
1717
static void
1718
lua_pushrandom(lua_State *L, FuzzedDataProvider *fdp)
1719
4.65k
{
1720
4.65k
  uint8_t idx = fdp->ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(push_func) - 1);
1721
1722
4.65k
  push_func[idx](L, fdp);
1723
1724
4.65k
  bool is_set_mt = fdp->ConsumeBool();
1725
4.65k
  if (is_set_mt) {
1726
2.08k
    luaL_getmetatable(L, TYPE_NAME_TORTURE);
1727
2.08k
    lua_setmetatable(L, -2);
1728
2.08k
  }
1729
4.65k
}
1730
1731
/* void lua_createtable(lua_State *L, int narr, int nrec); */
1732
/* [-0, +1, m] */
1733
static void
1734
__lua_createtable(lua_State *L, FuzzedDataProvider *fdp)
1735
62
{
1736
62
  int nrows = fdp->ConsumeIntegral<uint8_t>();
1737
  /* XXX: Lua associative arrays. */
1738
62
  lua_createtable(L, nrows, 0);
1739
7.36k
  for (int i = 0; i < nrows; i++) {
1740
7.29k
    lua_pushnumber(L, i);
1741
7.29k
    lua_rawseti(L, -2, i + 1);
1742
7.29k
  }
1743
62
  assert(lua_gettop(L) != 0);
1744
62
}
1745
1746
static lua_func func[] = {
1747
  &__lua_call,
1748
  &__lua_checkstack,
1749
  &__lua_concat,
1750
  &__lua_createtable,
1751
  &__lua_gc,
1752
  &__lua_getallocf,
1753
  &__lua_getfield,
1754
  &__lua_getglobal,
1755
  &__lua_gethook,
1756
  &__lua_gethookcount,
1757
  &__lua_gethookmask,
1758
  &__lua_getinfo,
1759
  &__lua_getmetatable,
1760
  &__lua_getstack,
1761
  &__lua_gettable,
1762
  &__lua_gettop,
1763
  &__lua_getupvalue,
1764
  &__lua_insert,
1765
  &__lua_isboolean,
1766
  &__lua_iscfunction,
1767
  &__lua_isfunction,
1768
  &__lua_islightuserdata,
1769
  &__lua_isnil,
1770
  &__lua_isnone,
1771
  &__lua_isnoneornil,
1772
  &__lua_isnumber,
1773
  &__lua_isstring,
1774
  &__lua_istable,
1775
  &__lua_isthread,
1776
  &__lua_isuserdata,
1777
  &__luaL_callmeta,
1778
  &__luaL_checkany,
1779
  &__luaL_checkinteger,
1780
  &__luaL_checknumber,
1781
  &__luaL_checkstack,
1782
  &__luaL_checkstring,
1783
  &__luaL_checktype,
1784
  &__luaL_getmetafield,
1785
  &__luaL_loadstring,
1786
  &__luaL_ref,
1787
  &__luaL_tolstring,
1788
  &__luaL_traceback,
1789
  &__luaL_where,
1790
  &__lua_newtable,
1791
  &__lua_newthread,
1792
  &__lua_newuserdata,
1793
  &__lua_next,
1794
  &__lua_pcall,
1795
  &__lua_pop,
1796
  &__lua_pushboolean,
1797
  &__lua_pushcclosure,
1798
  &__lua_pushcfunction,
1799
  &__lua_pushfstring,
1800
  &__lua_pushinteger,
1801
  &__lua_pushlstring,
1802
  &__lua_pushnil,
1803
  &__lua_pushnumber,
1804
  &__lua_pushstring,
1805
  &__lua_pushthread,
1806
  &__lua_pushvalue,
1807
  &__lua_rawequal,
1808
  &__lua_rawget,
1809
  &__lua_rawgeti,
1810
  &__lua_rawset,
1811
  &__lua_rawseti,
1812
  &__lua_register,
1813
  &__lua_remove,
1814
  &__lua_replace,
1815
  &__lua_resume,
1816
  &__lua_setfield,
1817
  &__lua_setglobal,
1818
  &__lua_setmetatable,
1819
  &__lua_settable,
1820
  &__lua_settop,
1821
  &__lua_setupvalue,
1822
  &__lua_status,
1823
  &__lua_toboolean,
1824
  &__lua_tocfunction,
1825
  &__lua_tointeger,
1826
  &__lua_tointegerx,
1827
  &__lua_tolstring,
1828
  &__lua_tonumber,
1829
  &__lua_topointer,
1830
  &__lua_tostring,
1831
  &__lua_tothread,
1832
  &__lua_touserdata,
1833
  &__lua_type,
1834
  &__lua_typename,
1835
  &__lua_upvalueid,
1836
  &__lua_xmove,
1837
#if LUA_VERSION_NUM == 501
1838
  &__lua_cpcall,
1839
  &__lua_equal,
1840
  &__lua_getfenv,
1841
  &__lua_lessthan,
1842
  &__lua_objlen,
1843
  &__lua_setfenv,
1844
#endif /* LUA_VERSION_NUM */
1845
#if LUA_VERSION_NUM > 501
1846
  &__lua_absindex,
1847
  &__lua_arith,
1848
  &__lua_compare,
1849
  &__lua_copy,
1850
  &__luaL_checkversion,
1851
  &__lua_len,
1852
  &__luaL_len,
1853
  &__luaL_setmetatable,
1854
  &__lua_rawgetp,
1855
  &__lua_rawlen,
1856
  &__lua_tonumberx,
1857
  &__lua_version,
1858
#endif /* LUA_VERSION_NUM */
1859
#if LUA_VERSION_NUM > 502
1860
  &__lua_geti,
1861
  &__lua_isyieldable,
1862
  &__lua_rotate,
1863
  &__lua_seti,
1864
  &__lua_stringtonumber,
1865
#endif /* LUA_VERSION_NUM */
1866
#if LUA_VERSION_NUM > 503
1867
  &__lua_getiuservalue,
1868
  &__lua_setiuservalue,
1869
#endif /* LUA_VERSION_NUM */
1870
#if LUA_VERSION_NUM > 501 && LUA_VERSION_NUM < 504
1871
  &__lua_setuservalue,
1872
  &__lua_getuservalue,
1873
#endif /* LUA_VERSION_NUM */
1874
#ifdef LUAJIT
1875
  &__lua_copy,
1876
  &__lua_isyieldable,
1877
  &__luaL_setmetatable,
1878
  &__lua_tonumberx,
1879
  &__lua_version,
1880
#endif /* LUAJIT */
1881
};
1882
1883
extern "C" int
1884
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
1885
2.36k
{
1886
2.36k
  lua_State *L = luaL_newstate();
1887
2.36k
  if (L == NULL)
1888
0
    return 0;
1889
1890
#if LUA_VERSION_NUM == 501
1891
  luaL_register(L, TYPE_NAME_TORTURE, TORTURE_meta);
1892
#else
1893
2.36k
  luaL_newmetatable(L, TYPE_NAME_TORTURE);
1894
2.36k
  luaL_setfuncs(L, TORTURE_meta, 0);
1895
2.36k
#endif /* LUA_VERSION_NUM */
1896
1897
2.36k
  FuzzedDataProvider fdp(data, size);
1898
2.36k
  int start_slots = 2;
1899
7.09k
  for (int i = 1; i <= start_slots; i++)
1900
4.73k
    if (fdp.remaining_bytes() != 0)
1901
4.65k
      lua_pushrandom(L, &fdp);
1902
1903
2.36k
  if (lua_gettop(L) != 0 &&
1904
2.36k
      fdp.remaining_bytes() != 0) {
1905
2.25k
    __lua_gc(L, &fdp);
1906
2.25k
    __lua_sethook(L, &fdp);
1907
2.25k
    uint8_t idx = fdp.ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(func) - 1);
1908
2.25k
    func[idx](L, &fdp);
1909
2.25k
  }
1910
1911
2.36k
  lua_settop(L, 0);
1912
2.36k
  lua_close(L);
1913
1914
2.36k
  return 0;
1915
2.36k
}