Skip to content

Commit 7a3f19b

Browse files
committed
Ensure that buffer with Luau compiled code is always freed
1 parent 55a5d7e commit 7a3f19b

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

mlua-sys/src/luau/compat.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -326,12 +326,16 @@ pub unsafe fn luaL_loadbufferenv(
326326
mut size: usize,
327327
name: *const c_char,
328328
mode: *const c_char,
329-
env: c_int,
329+
mut env: c_int,
330330
) -> c_int {
331331
extern "C" {
332332
fn free(p: *mut c_void);
333333
}
334334

335+
unsafe extern "C-unwind" fn data_dtor(data: *mut c_void) {
336+
free(*(data as *mut *mut c_char) as *mut c_void);
337+
}
338+
335339
let chunk_is_text = size == 0 || (*data as u8) >= b'\t';
336340
if !mode.is_null() {
337341
let modeb = CStr::from_ptr(mode).to_bytes();
@@ -345,9 +349,16 @@ pub unsafe fn luaL_loadbufferenv(
345349
}
346350

347351
if chunk_is_text {
352+
if env < 0 {
353+
env -= 1;
354+
}
355+
let data_ud = lua_newuserdatadtor(L, mem::size_of::<*mut c_char>(), data_dtor) as *mut *mut c_char;
348356
let data = luau_compile_(data, size, ptr::null_mut(), &mut size);
357+
ptr::write(data_ud, data);
358+
// By deferring the `free(data)` to the userdata destructor, we ensure that
359+
// even if `luau_load` throws an error, the `data` is still released.
349360
let ok = luau_load(L, name, data, size, env) == 0;
350-
free(data as *mut c_void);
361+
lua_replace(L, -2); // replace data with the result
351362
if !ok {
352363
return LUA_ERRSYNTAX;
353364
}

src/state/raw.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -327,10 +327,10 @@ impl RawLua {
327327
Some(ChunkMode::Text) => cstr!("t"),
328328
None => cstr!("bt"),
329329
};
330-
let status = if cfg!(not(feature = "luau")) || self.unlikely_memory_error() {
330+
let status = if self.unlikely_memory_error() {
331331
self.load_chunk_inner(state, name, env, mode, source)
332332
} else {
333-
// Only Luau can trigger an exception during chunk loading
333+
// Luau and Lua 5.2 can trigger an exception during chunk loading
334334
protect_lua!(state, 0, 1, |state| {
335335
self.load_chunk_inner(state, name, env, mode, source)
336336
})?

0 commit comments

Comments
 (0)