/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 | } |