Coverage Report

Created: 2025-07-11 06:33

/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
60
cfunction(lua_State *L) {
39
60
  lua_gettop(L);
40
60
  return 0;
41
60
}
42
43
2.37k
#define TYPE_NAME_TORTURE "torture_test"
44
24
#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
155
{
57
155
  auto str = fdp->ConsumeRandomLengthString(max_str_len);
58
155
  int top = lua_gettop(L);
59
155
  lua_pushstring(L, str.c_str());
60
155
  assert(lua_gettop(L) == top + 1);
61
155
}
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
90
{
68
90
  uint8_t n = fdp->ConsumeIntegral<uint8_t>();
69
90
  int top = lua_gettop(L);
70
90
  lua_pushboolean(L, n);
71
90
  assert(lua_gettop(L) == top + 1);
72
90
}
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
10
{
79
10
  int top = lua_gettop(L);
80
10
  uint8_t n = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
81
10
  lua_pop(L, n);
82
10
  assert(lua_gettop(L) == top - n);
83
10
}
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
24
{
90
24
  int top = lua_gettop(L);
91
24
  uint8_t n = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
92
24
  lua_isnumber(L, n);
93
24
  assert(lua_gettop(L) == top);
94
24
}
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
26
{
112
26
  int top = lua_gettop(L);
113
26
  auto index = fdp->ConsumeIntegralInRange(1, top);
114
26
  int isnum;
115
26
  lua_tonumberx(L, index, &isnum);
116
26
  assert(isnum == 0 || isnum == 1);
117
26
  assert(lua_gettop(L) == top);
118
26
}
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
49
{
125
49
  uint8_t n = fdp->ConsumeIntegral<uint8_t>();
126
49
  int rc = lua_checkstack(L, n);
127
49
  assert(rc != 0);
128
49
}
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
51
{
135
51
  int top = lua_gettop(L);
136
51
  uint8_t n = fdp->ConsumeIntegralInRange<uint8_t>(0, top);
137
97
  for (int i = 1; i <= n; i++) {
138
65
    int t = lua_type(L, -i);
139
65
    if (t != LUA_TNUMBER &&
140
65
        t != LUA_TSTRING)
141
19
      return;
142
65
  }
143
32
  lua_concat(L, n);
144
32
  assert(lua_gettop(L) == top - n + 1);
145
32
}
146
147
/* int lua_gettop(lua_State *L); */
148
/* [-0, +0, -] */
149
static void
150
__lua_gettop(lua_State *L, FuzzedDataProvider *fdp)
151
2
{
152
2
  int rc = lua_gettop(L);
153
2
  assert(rc >= 0);
154
2
}
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
18
{
161
18
  int top = lua_gettop(L);
162
18
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
163
18
  lua_insert(L, index);
164
18
  assert(lua_gettop(L) == top - 1 + 1);
165
18
}
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
22
{
172
22
  int top = lua_gettop(L);
173
22
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
174
22
  int rc = lua_isboolean(L, index);
175
22
  assert(rc == 0 || rc == 1);
176
22
}
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
18
{
183
18
  int top = lua_gettop(L);
184
18
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
185
18
  int rc = lua_iscfunction(L, index);
186
18
  assert(rc == 0 || rc == 1);
187
18
}
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
20
{
194
20
  int top = lua_gettop(L);
195
20
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
196
20
  int rc = lua_isfunction(L, index);
197
20
  assert(rc == 0 || rc == 1);
198
20
}
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
20
{
205
20
  int top = lua_gettop(L);
206
20
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
207
20
  int rc = lua_isnil(L, index);
208
20
  assert(rc == 0 || rc == 1);
209
20
}
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
11
{
216
11
  int top = lua_gettop(L);
217
11
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
218
11
  int rc = lua_isnone(L, index);
219
11
  assert(rc == 0 || rc == 1);
220
11
  assert(lua_gettop(L) == top);
221
11
}
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
202
{
261
202
  int top = lua_gettop(L);
262
202
  uint8_t n = fdp->ConsumeIntegral<uint8_t>();
263
202
  lua_pushinteger(L, n);
264
202
  assert(lua_gettop(L) == top + 1);
265
202
}
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
127
{
272
127
  int top = lua_gettop(L);
273
127
  auto str = fdp->ConsumeRandomLengthString(max_str_len);
274
127
  lua_pushlstring(L, str.c_str(), str.size());
275
127
  assert(lua_gettop(L) == top + 1);
276
127
}
277
278
/* void lua_pushnil(lua_State *L); */
279
/* [-0, +1, -] */
280
static void
281
__lua_pushnil(lua_State *L, FuzzedDataProvider *fdp)
282
674
{
283
674
  int top = lua_gettop(L);
284
674
  lua_pushnil(L);
285
674
  assert(lua_gettop(L) == top + 1);
286
674
}
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
268
{
293
268
  int top = lua_gettop(L);
294
268
  uint8_t n = fdp->ConsumeIntegral<uint8_t>();
295
268
  lua_pushnumber(L, n);
296
268
  assert(lua_gettop(L) == top + 1);
297
268
}
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
7
{
304
7
  int top = lua_gettop(L);
305
7
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
306
7
  lua_pushvalue(L, index);
307
7
  assert(lua_gettop(L) == top + 1);
308
7
}
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
24
{
326
24
  int top = lua_gettop(L);
327
24
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
328
24
  lua_replace(L, index);
329
24
  assert(lua_gettop(L) == top - 1);
330
24
}
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
7
{
337
7
  int top = lua_gettop(L);
338
7
  auto str = fdp->ConsumeRandomLengthString(max_str_len);
339
7
  lua_setglobal(L, str.c_str());
340
7
  assert(lua_gettop(L) == top - 1);
341
7
}
342
343
/* void lua_settop(lua_State *L, int index); */
344
/* [-?, +?, -] */
345
static void
346
__lua_settop(lua_State *L, FuzzedDataProvider *fdp)
347
6
{
348
6
  int top = lua_gettop(L);
349
6
  int grow_slots = 2;
350
6
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top + grow_slots);
351
6
  lua_settop(L, index);
352
6
  assert(lua_gettop(L) == index);
353
6
}
354
355
/* int lua_status(lua_State *L); */
356
/* [-0, +0, -] */
357
static void
358
__lua_status(lua_State *L, FuzzedDataProvider *fdp)
359
5
{
360
5
  int rc = lua_status(L);
361
5
  assert(rc == 0 || rc == LUA_YIELD);
362
5
}
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
9
{
369
9
  int top = lua_gettop(L);
370
9
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
371
9
  int rc = lua_toboolean(L, index);
372
9
  assert(rc == 0 || rc == 1);
373
9
}
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
9
{
380
9
  int top = lua_gettop(L);
381
9
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
382
9
  lua_tointeger(L, index);
383
9
  assert(lua_gettop(L) == top);
384
9
}
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
9
{
391
9
  int top = lua_gettop(L);
392
9
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
393
9
  int isnum;
394
9
  lua_tointegerx(L, index, &isnum);
395
9
  assert(isnum == 0 || isnum == 1);
396
9
  assert(lua_gettop(L) == top);
397
9
}
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
25
{
404
25
  int top = lua_gettop(L);
405
25
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
406
25
  lua_tolstring(L, index, NULL);
407
25
  assert(lua_gettop(L) == top);
408
25
}
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
9
{
415
9
  int top = lua_gettop(L);
416
9
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
417
9
  lua_tostring(L, index);
418
9
  assert(lua_gettop(L) == top);
419
9
}
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
21
{
426
21
  int top = lua_gettop(L);
427
21
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
428
21
  int type = lua_type(L, index);
429
21
  assert(type == LUA_TBOOLEAN       ||
430
21
         type == LUA_TFUNCTION      ||
431
21
         type == LUA_TLIGHTUSERDATA ||
432
21
         type == LUA_TNIL           ||
433
21
         type == LUA_TNUMBER        ||
434
21
         type == LUA_TSTRING        ||
435
21
         type == LUA_TTABLE         ||
436
21
         type == LUA_TTHREAD        ||
437
21
         type == LUA_TUSERDATA      ||
438
21
         type == LUA_TNONE);
439
21
  assert(lua_gettop(L) == top);
440
21
}
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
1
{
447
1
  auto name = fdp->ConsumeRandomLengthString(max_str_len);
448
1
  int top = lua_gettop(L);
449
1
  lua_getglobal(L, name.c_str());
450
1
  assert(lua_gettop(L) == top + 1);
451
1
}
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
25
{
458
25
  int top = lua_gettop(L);
459
25
  int funcindex = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
460
25
  int n = fdp->ConsumeIntegral<uint8_t>();
461
25
  lua_setupvalue(L, funcindex, n);
462
25
  assert(lua_gettop(L) == top);
463
25
}
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
23
{
470
23
  int top = lua_gettop(L);
471
23
  int funcindex = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
472
23
  int n = fdp->ConsumeIntegral<uint8_t>();
473
23
  lua_getupvalue(L, funcindex, n);
474
23
  assert(lua_gettop(L) == top || lua_gettop(L) == top + 1);
475
23
}
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
16
{
493
16
  int top = lua_gettop(L);
494
16
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
495
16
  int rc = lua_islightuserdata(L, index);
496
16
  assert(rc == 0 || rc == 1);
497
16
}
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
25
{
504
25
  int top = lua_gettop(L);
505
25
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
506
25
  int rc = lua_isuserdata(L, index);
507
25
  assert(rc == 0 || rc == 1);
508
25
}
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
11
{
515
11
  int top = lua_gettop(L);
516
11
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
517
11
  int rc = lua_isthread(L, index);
518
11
  assert(rc == 0 || rc == 1);
519
11
}
520
521
/* int lua_pushthread(lua_State *L); */
522
/* [-0, +1, -] */
523
static void
524
__lua_pushthread(lua_State *L, FuzzedDataProvider *fdp)
525
4
{
526
4
  int top = lua_gettop(L);
527
4
  int rc = lua_pushthread(L);
528
4
  assert(rc == 1);
529
4
  assert(lua_gettop(L) == top + 1);
530
4
}
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
19
{
537
19
  int top = lua_gettop(L);
538
19
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
539
19
  if (!lua_istable(L, index))
540
9
    return;
541
10
  lua_pushnil(L);  /* first key */
542
10
  lua_next(L, index);
543
10
  assert(lua_gettop(L) - top - 1 <= 2);
544
10
}
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
41
{
577
  /* Maximum n is 255 in lua_pushcclosure(3). */
578
41
  int n = fdp->ConsumeIntegralInRange<uint8_t>(1, 10);
579
195
  for (int i = 1; i < n; i++)
580
154
    lua_pushnumber(L, i);
581
41
  lua_pushcclosure(L, cfunction, n);
582
41
}
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
955
{
589
955
  (void)fdp;
590
955
  int top = lua_gettop(L);
591
955
  lua_pushcfunction(L, cfunction);
592
955
  assert(lua_gettop(L) == top + 1);
593
955
}
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.55k
{
611
1.55k
  int top = lua_gettop(L);
612
1.55k
  lua_newtable(L);
613
1.55k
  assert(lua_gettop(L) == top + 1);
614
1.55k
}
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
806
{
621
806
  int top = lua_gettop(L);
622
806
  lua_newthread(L);
623
806
  assert(lua_gettop(L) == top + 1);
624
806
}
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
21
{
631
21
  int top = lua_gettop(L);
632
21
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
633
21
  const char* name = lua_typename(L, index);
634
21
  assert(name);
635
21
  assert(lua_gettop(L) == top);
636
21
}
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.28k
{
662
2.28k
  int top = lua_gettop(L);
663
2.28k
  uint8_t idx = fdp->ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(gc_mode) - 1);
664
2.28k
#if LUA_VERSION_NUM > 503
665
2.28k
  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.28k
  } 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.28k
    lua_gc(L, gc_mode[idx], 0);
676
#else
677
  lua_gc(L, gc_mode[idx], 0);
678
#endif /* LUA_VERSION_NUM */
679
2.28k
  assert(lua_gettop(L) == top);
680
2.28k
}
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
6
{
693
6
  (void)L;
694
6
  (void)ar;
695
6
}
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.26k
{
702
2.26k
  int top = lua_gettop(L);
703
2.26k
  uint8_t idx = fdp->ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(hook_mode) - 1);
704
2.26k
  lua_sethook(L, Hook, hook_mode[idx], 1);
705
2.26k
  assert(lua_gettop(L) == top);
706
2.26k
}
707
708
/* lua_Hook lua_gethook(lua_State *L); */
709
/* [-0, +0, –] */
710
static void
711
__lua_gethook(lua_State *L, FuzzedDataProvider *fdp)
712
2
{
713
2
  int top = lua_gettop(L);
714
2
  lua_gethook(L);
715
2
  assert(lua_gettop(L) == top);
716
2
}
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
2
{
734
2
  int top = lua_gettop(L);
735
2
  int hook_mask = lua_gethookmask(L);
736
2
  assert(hook_mask >= 0);
737
2
  assert(lua_gettop(L) == top);
738
2
}
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
18
{
745
18
  int top = lua_gettop(L);
746
18
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
747
18
  if (!lua_istable(L, index))
748
6
    return;
749
12
  uint8_t key = fdp->ConsumeIntegral<uint8_t>();
750
12
  lua_pushnumber(L, key);
751
12
  top = lua_gettop(L);
752
12
  lua_rawget(L, index);
753
12
  assert(lua_gettop(L) == top);
754
12
}
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
39
{
761
39
  int top = lua_gettop(L);
762
39
  if (top == 0)
763
0
    return;
764
39
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
765
39
  if (!lua_istable(L, index))
766
6
    return;
767
33
  uint8_t key = fdp->ConsumeIntegral<uint8_t>();
768
33
  uint8_t value = fdp->ConsumeIntegral<uint8_t>();
769
33
  lua_pushnumber(L, value);
770
33
  lua_pushnumber(L, key);
771
33
  top = lua_gettop(L);
772
33
  lua_rawset(L, index);
773
33
  assert(lua_gettop(L) == top - 2);
774
33
}
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
36
{
781
36
  int top = lua_gettop(L);
782
36
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
783
36
  if (!lua_istable(L, index))
784
10
    return;
785
26
  int n = fdp->ConsumeIntegral<uint8_t>();
786
26
  __lua_pushnumber(L, fdp);
787
26
  top = lua_gettop(L);
788
26
  lua_rawseti(L, index, n);
789
26
  assert(lua_gettop(L) == top - 1);
790
26
}
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
27
{
797
27
  int top = lua_gettop(L);
798
27
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
799
27
  if (!lua_istable(L, index))
800
7
    return;
801
20
  int i = fdp->ConsumeIntegral<uint8_t>();
802
20
  lua_rawgeti(L, index, i);
803
20
  assert(lua_gettop(L) == top + 1);
804
20
}
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
111
{
877
111
  int top = lua_gettop(L);
878
111
  uint8_t index1 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
879
111
  uint8_t index2 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
880
111
  if ((lua_type(L, index1) != LUA_TNUMBER) ||
881
111
      (lua_type(L, index2) != LUA_TNUMBER))
882
35
    return;
883
76
  int op_idx = fdp->ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(cmp_op) - 1);
884
76
  int rc = lua_compare(L, index1, index2, cmp_op[op_idx]);
885
76
  assert(rc == 0 || rc == 1);
886
76
  assert(lua_gettop(L) == top);
887
76
}
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
10
{
896
10
  int top = lua_gettop(L);
897
10
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
898
10
  lua_rawlen(L, index);
899
10
  assert(lua_gettop(L) == top);
900
10
}
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
20
{
937
20
  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
20
  int8_t index = fdp->ConsumeIntegralInRange<int8_t>(-top, top);
945
20
  int idx = lua_absindex(L, index);
946
20
  assert(idx > 0);
947
20
  assert(lua_gettop(L) == top);
948
20
}
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
2
{
977
2
  int top = lua_gettop(L);
978
2
  if ((lua_type(L, 1) != LUA_TNUMBER) ||
979
2
      (lua_type(L, 2) != LUA_TNUMBER))
980
2
    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
16
{
1001
16
  luaL_getmetatable(L, TYPE_NAME_TORTURE);
1002
16
  int top = lua_gettop(L);
1003
16
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1004
16
  lua_setmetatable(L, index);
1005
16
  assert(lua_gettop(L) == top - 1);
1006
16
}
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
8
{
1013
8
  int top = lua_gettop(L);
1014
8
  luaL_setmetatable(L, TYPE_NAME_TORTURE);
1015
8
  assert(lua_gettop(L) == top);
1016
8
}
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
25
{
1064
25
  int top = lua_gettop(L);
1065
25
  int min_n = 1;
1066
25
  uint8_t idx = fdp->ConsumeIntegralInRange<uint8_t>(1, top - min_n);
1067
25
  uint8_t n = fdp->ConsumeIntegralInRange<uint8_t>(1, top - idx);
1068
25
  lua_rotate(L, idx, n);
1069
25
  assert(lua_gettop(L) == top);
1070
25
}
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
49
{
1079
49
  int top = lua_gettop(L);
1080
49
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1081
49
  if (!lua_istable(L, index))
1082
8
    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
51
{
1097
51
  int top = lua_gettop(L);
1098
51
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1099
51
  if (!lua_istable(L, index))
1100
4
    return;
1101
47
  int i = fdp->ConsumeIntegral<uint8_t>();
1102
47
  lua_geti(L, index, i);
1103
47
  assert(lua_gettop(L) == top + 1);
1104
47
}
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
4
{
1151
4
  int top = lua_gettop(L);
1152
4
  lua_register(L, "cfunction", cfunction);
1153
4
  assert(lua_gettop(L) == top);
1154
4
}
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
2
{
1166
2
  lua_State *co = lua_newthread(L);
1167
2
  lua_pushcfunction(co, cfunction);
1168
2
  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
2
  int nres;
1175
2
  res = lua_resume(co, L, 0, &nres);
1176
2
#endif /* LUA_VERSION_NUM */
1177
  /* assert(res == LUA_OK); */
1178
2
  (void)res;
1179
2
  lua_settop(co, 0);
1180
2
}
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
150
{
1187
150
  int top = lua_gettop(L);
1188
150
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1189
150
  if (lua_type(L, index) != LUA_TTABLE)
1190
4
    return;
1191
146
  auto k = fdp->ConsumeRemainingBytesAsString();
1192
146
  lua_setfield(L, index, k.c_str());
1193
146
  assert(lua_gettop(L) == top - 1);
1194
146
}
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
14
{
1201
14
  int top = lua_gettop(L);
1202
14
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1203
14
  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
14
  int type = lua_type(L, index);
1209
14
  if (type == LUA_TUSERDATA  ||
1210
14
      type == LUA_TTHREAD    ||
1211
14
      type == LUA_TTABLE     ||
1212
14
#if LUA_VERSION_NUM > 503 || defined(LUAJIT)
1213
14
      type == LUA_TSTRING    ||
1214
14
#endif /* LUA_VERSION_NUM */
1215
14
      type == LUA_TFUNCTION)
1216
11
    assert(p);
1217
3
  else
1218
3
    assert(p == NULL);
1219
14
  assert(lua_gettop(L) == top);
1220
14
}
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
23
{
1227
23
  int top = lua_gettop(L);
1228
23
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1229
23
  lua_tocfunction(L, index);
1230
23
  assert(lua_gettop(L) == top);
1231
23
}
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
12
{
1238
12
  int top = lua_gettop(L);
1239
12
  lua_createtable(L, 0, 1);
1240
1241
12
  lua_pushstring(L, "language");
1242
12
  lua_pushstring(L, "Lua");
1243
12
  lua_settable(L, -3);
1244
1245
12
  assert(lua_gettop(L) == top + 1);
1246
12
}
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
212
{
1253
212
  int top = lua_gettop(L);
1254
212
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1255
212
  if (lua_type(L, index) != LUA_TTABLE)
1256
8
    return;
1257
204
  auto k = fdp->ConsumeRemainingBytesAsString();
1258
204
  lua_getfield(L, index, k.c_str());
1259
204
  assert(lua_gettop(L) == top + 1);
1260
204
}
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
38
{
1267
38
  uint8_t size = fdp->ConsumeIntegral<uint8_t>();
1268
38
  lua_newuserdata(L, size);
1269
38
}
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
19
{
1294
19
  int top = lua_gettop(L);
1295
19
  uint8_t index = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1296
19
  lua_tothread(L, index);
1297
19
  assert(lua_gettop(L) == top);
1298
19
}
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
27
{
1305
27
  int top = lua_gettop(L);
1306
27
  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
27
  if (lua_type(L, narg) != LUA_TNUMBER)
1312
26
    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
9
{
1322
9
  int top = lua_gettop(L);
1323
9
  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
9
  if (lua_type(L, arg) != LUA_TNUMBER)
1329
7
    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
23
{
1339
23
  int top = lua_gettop(L);
1340
23
  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
23
  if (lua_type(L, arg) != LUA_TSTRING)
1346
20
    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
12
{
1356
12
  int top = lua_gettop(L);
1357
12
  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
12
  int type = lua_type(L, arg);
1363
12
  luaL_checktype(L, arg, type);
1364
12
  assert(lua_gettop(L) == top);
1365
12
}
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
8
{
1372
8
  int top = lua_gettop(L);
1373
8
  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
8
  luaL_checkany(L, arg);
1379
8
  assert(lua_gettop(L) == top);
1380
8
}
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
22
{
1388
22
  lua_newuserdatauv(L, 1, 0);
1389
22
  __lua_pushnumber(L, fdp);
1390
22
  int n = 1;
1391
22
  lua_setiuservalue(L, -2, n);
1392
22
  int top = lua_gettop(L);
1393
22
  lua_getiuservalue(L, -1, n);
1394
22
  assert(lua_gettop(L) == top + 1);
1395
22
}
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
20
{
1404
20
  __lua_newuserdata(L, fdp);
1405
20
  __lua_pushnumber(L, fdp);
1406
20
  uint8_t n = fdp->ConsumeIntegral<uint8_t>();
1407
20
  int top = lua_gettop(L);
1408
20
  lua_setiuservalue(L, -2, n);
1409
20
  assert(lua_gettop(L) == top - 1);
1410
20
}
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
5
{
1418
5
  int funcindex = -1;
1419
5
  lua_Debug ar;
1420
5
  lua_pushcfunction(L, cfunction);
1421
5
  int n = fdp->ConsumeIntegral<uint8_t>();
1422
5
  lua_setupvalue(L, funcindex, n);
1423
5
  assert(lua_getinfo(L, ">u", &ar) == 1);
1424
5
  if (ar.nups == 0)
1425
5
    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
41
{
1437
41
  int top = lua_gettop(L);
1438
41
  if (top < 2)
1439
0
    return;
1440
41
  uint8_t index1 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1441
41
  uint8_t index2 = fdp->ConsumeIntegralInRange<uint8_t>(1, top);
1442
41
  lua_rawequal(L, index1, index2);
1443
41
  assert(lua_gettop(L) == top);
1444
41
}
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
7
{
1451
7
  int top = lua_gettop(L);
1452
7
  auto buf = fdp->ConsumeRandomLengthString(max_str_len);
1453
7
  luaL_traceback(L, L, buf.c_str(), 1);
1454
7
  assert(lua_gettop(L) == top + 1);
1455
7
}
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
4
    return;
1486
4
  lua_copy(L, fromidx, toidx);
1487
4
  assert(lua_gettop(L) == top);
1488
4
}
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
25
{
1509
25
  int top = lua_gettop(L);
1510
25
  auto str = fdp->ConsumeRandomLengthString(max_str_len);
1511
25
  size_t sz = lua_stringtonumber(L, str.c_str());
1512
25
  if (sz == 0) {
1513
24
    assert(lua_gettop(L) == top);
1514
24
  } else {
1515
1
    assert(lua_gettop(L) == top + 1);
1516
1
    assert(lua_isnumber(L, -1) == 1);
1517
1
  }
1518
25
}
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
26
{
1527
26
  int top = lua_gettop(L);
1528
26
  auto idx = fdp->ConsumeIntegralInRange(1, top);
1529
26
  if (lua_type(L, idx) != LUA_TTABLE)
1530
12
    return;
1531
14
  void *p = malloc(1);
1532
14
  lua_rawgetp(L, idx, p);
1533
14
  free(p);
1534
14
  assert(lua_gettop(L) == top + 1);
1535
14
}
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
26
{
1544
26
  int top = lua_gettop(L);
1545
26
  auto idx = fdp->ConsumeIntegralInRange(1, top);
1546
26
  if (lua_type(L, idx) != LUA_TTABLE &&
1547
26
      lua_type(L, idx) != LUA_TSTRING)
1548
8
    return;
1549
18
  lua_len(L, idx);
1550
18
  assert(lua_gettop(L) == top + 1);
1551
18
}
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
19
{
1560
19
  int top = lua_gettop(L);
1561
19
  auto index = fdp->ConsumeIntegralInRange(1, top);
1562
19
  int type = lua_type(L, index);
1563
19
  if (type == LUA_TFUNCTION  ||
1564
19
      type == LUA_TTHREAD    ||
1565
19
      type == LUA_TNUMBER    ||
1566
19
      type == LUA_TBOOLEAN   ||
1567
19
      type == LUA_TNIL       ||
1568
19
      type == LUA_TUSERDATA)
1569
11
    return;
1570
8
  luaL_len(L, index);
1571
8
  assert(lua_gettop(L) == top);
1572
8
}
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
4
{
1580
4
  int top = lua_gettop(L);
1581
4
  void *state;
1582
4
  lua_getallocf(L, &state);
1583
4
  assert(lua_gettop(L) == top);
1584
4
}
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
26
{
1591
26
  int top = lua_gettop(L);
1592
26
  auto idx = fdp->ConsumeIntegralInRange(1, top);
1593
26
  if (lua_type(L, idx) != LUA_TTABLE)
1594
6
    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
2
{
1617
2
  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
2
  lua_Number v = lua_version(L);
1623
2
  assert(v != 0);
1624
2
#endif /* LUA_VERSION_NUM */
1625
2
  assert(lua_gettop(L) == top);
1626
2
}
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
32
{
1634
32
  int top = lua_gettop(L);
1635
32
  auto obj = fdp->ConsumeIntegralInRange(1, top);
1636
32
  const char e[] = "xxx";
1637
32
  luaL_getmetafield(L, obj, e);
1638
32
  assert(lua_gettop(L) == top || lua_gettop(L) == top + 1);
1639
32
}
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
49
{
1646
49
  int top = lua_gettop(L);
1647
  /* Function to be called. */
1648
49
  lua_pushcfunction(L, cfunction);
1649
49
  int nargs = 0;
1650
49
  int nresults = 0;
1651
49
  lua_call(L, nargs, nresults);
1652
49
  assert(lua_gettop(L) == top + nresults - nargs);
1653
49
}
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
1
{
1660
1
  int top = lua_gettop(L);
1661
  /* Function to be called. */
1662
1
  lua_pushcfunction(L, cfunction);
1663
1
  int nargs = 0;
1664
1
  int nresults = 0;
1665
1
  int res = lua_pcall(L, nargs, nresults, 0);
1666
1
  assert(res == LUA_OK);
1667
1
  assert(lua_gettop(L) == top + nresults - nargs);
1668
1
}
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
24
{
1686
24
  int top = lua_gettop(L);
1687
24
  auto obj = fdp->ConsumeIntegralInRange(1, top);
1688
24
  luaL_callmeta(L, obj, MT_FUNC_NAME_TORTURE);
1689
24
  assert(lua_gettop(L) == top || lua_gettop(L) == top + 1);
1690
24
}
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
5
{
1697
5
  int top = lua_gettop(L);
1698
5
  luaL_where(L, 1);
1699
5
  assert(lua_gettop(L) == top + 1);
1700
5
}
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.66k
{
1720
4.66k
  uint8_t idx = fdp->ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(push_func) - 1);
1721
1722
4.66k
  push_func[idx](L, fdp);
1723
1724
4.66k
  bool is_set_mt = fdp->ConsumeBool();
1725
4.66k
  if (is_set_mt) {
1726
2.07k
    luaL_getmetatable(L, TYPE_NAME_TORTURE);
1727
2.07k
    lua_setmetatable(L, -2);
1728
2.07k
  }
1729
4.66k
}
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
60
{
1736
60
  int nrows = fdp->ConsumeIntegral<uint8_t>();
1737
  /* XXX: Lua associative arrays. */
1738
60
  lua_createtable(L, nrows, 0);
1739
7.87k
  for (int i = 0; i < nrows; i++) {
1740
7.81k
    lua_pushnumber(L, i);
1741
7.81k
    lua_rawseti(L, -2, i + 1);
1742
7.81k
  }
1743
60
  assert(lua_gettop(L) != 0);
1744
60
}
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.10k
  for (int i = 1; i <= start_slots; i++)
1900
4.73k
    if (fdp.remaining_bytes() != 0)
1901
4.66k
      lua_pushrandom(L, &fdp);
1902
1903
2.36k
  if (lua_gettop(L) != 0 &&
1904
2.36k
      fdp.remaining_bytes() != 0) {
1905
2.26k
    __lua_gc(L, &fdp);
1906
2.26k
    __lua_sethook(L, &fdp);
1907
2.26k
    uint8_t idx = fdp.ConsumeIntegralInRange<uint8_t>(0, ARRAY_SIZE(func) - 1);
1908
2.26k
    func[idx](L, &fdp);
1909
2.26k
  }
1910
1911
2.36k
  lua_settop(L, 0);
1912
2.36k
  lua_close(L);
1913
1914
2.36k
  return 0;
1915
2.36k
}