|
| 1 | +local tap = require('tap') |
| 2 | + |
| 3 | +-- Test file to demonstrate LuaJIT use-after-free in case of the |
| 4 | +-- error in `loadfile()`. |
| 5 | +-- See also: https://github.com/LuaJIT/LuaJIT/issues/1353. |
| 6 | +local test = tap.test('lj-1353-loadfile-err-use-after-free'):skipcond({ |
| 7 | + ['Too many GC objects on start'] = _TARANTOOL, |
| 8 | +}) |
| 9 | + |
| 10 | +test:plan(1) |
| 11 | + |
| 12 | +-- Determine the GC step size to finish the GC cycle in one step. |
| 13 | +local full_step = 1 |
| 14 | +while true do |
| 15 | + collectgarbage('collect') |
| 16 | + collectgarbage('setpause', 0) |
| 17 | + collectgarbage('setstepmul', full_step) |
| 18 | + if collectgarbage('step') then break end |
| 19 | + full_step = full_step + 1 |
| 20 | +end |
| 21 | + |
| 22 | +-- Check all possible GC step sizes. |
| 23 | +for i = 1, full_step do |
| 24 | + collectgarbage('collect') |
| 25 | + collectgarbage('setpause', 0) |
| 26 | + collectgarbage('setstepmul', i) |
| 27 | + repeat |
| 28 | + -- On Linux-like systems this always returns `nil`, with the |
| 29 | + -- error: "cannot read .: Is a directory" |
| 30 | + -- The string for the filename "@." may be collected during |
| 31 | + -- the call, and later the pointer to the "." from that string |
| 32 | + -- is used after the string is free. |
| 33 | + loadfile('.') |
| 34 | + until collectgarbage('step') |
| 35 | +end |
| 36 | + |
| 37 | +test:ok(true, 'no use-after-free error') |
| 38 | + |
| 39 | +test:done(true) |
0 commit comments