Coverage Report

Created: 2024-04-23 06:32

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