Skip to content

Commit 13dc2b5

Browse files
committed
Don't release Lua lock prematurely when when accessing Buffer bytes (Luau)
1 parent 7afbf74 commit 13dc2b5

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

src/buffer.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#[cfg(feature = "serde")]
22
use serde::ser::{Serialize, Serializer};
33

4+
use crate::state::RawLua;
45
use crate::types::ValueRef;
56

67
/// A Luau buffer type.
@@ -16,12 +17,14 @@ pub struct Buffer(pub(crate) ValueRef);
1617
impl Buffer {
1718
/// Copies the buffer data into a new `Vec<u8>`.
1819
pub fn to_vec(&self) -> Vec<u8> {
19-
unsafe { self.as_slice().to_vec() }
20+
let lua = self.0.lua.lock();
21+
self.as_slice(&lua).to_vec()
2022
}
2123

2224
/// Returns the length of the buffer.
2325
pub fn len(&self) -> usize {
24-
unsafe { self.as_slice().len() }
26+
let lua = self.0.lua.lock();
27+
self.as_slice(&lua).len()
2528
}
2629

2730
/// Returns `true` if the buffer is empty.
@@ -34,7 +37,8 @@ impl Buffer {
3437
/// Offset is 0-based.
3538
#[track_caller]
3639
pub fn read_bytes<const N: usize>(&self, offset: usize) -> [u8; N] {
37-
let data = unsafe { self.as_slice() };
40+
let lua = self.0.lua.lock();
41+
let data = self.as_slice(&lua);
3842
let mut bytes = [0u8; N];
3943
bytes.copy_from_slice(&data[offset..offset + N]);
4044
bytes
@@ -45,37 +49,40 @@ impl Buffer {
4549
/// Offset is 0-based.
4650
#[track_caller]
4751
pub fn write_bytes(&self, offset: usize, bytes: &[u8]) {
52+
let lua = self.0.lua.lock();
4853
let data = unsafe {
49-
let (buf, size) = self.as_raw_parts();
54+
let (buf, size) = self.as_raw_parts(&lua);
5055
std::slice::from_raw_parts_mut(buf, size)
5156
};
5257
data[offset..offset + bytes.len()].copy_from_slice(bytes);
5358
}
5459

55-
pub(crate) unsafe fn as_slice(&self) -> &[u8] {
56-
let (buf, size) = self.as_raw_parts();
57-
std::slice::from_raw_parts(buf, size)
60+
pub(crate) fn as_slice(&self, lua: &RawLua) -> &[u8] {
61+
unsafe {
62+
let (buf, size) = self.as_raw_parts(lua);
63+
std::slice::from_raw_parts(buf, size)
64+
}
5865
}
5966

6067
#[cfg(feature = "luau")]
61-
unsafe fn as_raw_parts(&self) -> (*mut u8, usize) {
62-
let lua = self.0.lua.lock();
68+
unsafe fn as_raw_parts(&self, lua: &RawLua) -> (*mut u8, usize) {
6369
let mut size = 0usize;
6470
let buf = ffi::lua_tobuffer(lua.ref_thread(), self.0.index, &mut size);
6571
mlua_assert!(!buf.is_null(), "invalid Luau buffer");
6672
(buf as *mut u8, size)
6773
}
6874

6975
#[cfg(not(feature = "luau"))]
70-
unsafe fn as_raw_parts(&self) -> (*mut u8, usize) {
76+
unsafe fn as_raw_parts(&self, lua: &RawLua) -> (*mut u8, usize) {
7177
unreachable!()
7278
}
7379
}
7480

7581
#[cfg(feature = "serde")]
7682
impl Serialize for Buffer {
7783
fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
78-
serializer.serialize_bytes(unsafe { self.as_slice() })
84+
let lua = self.0.lua.lock();
85+
serializer.serialize_bytes(self.as_slice(&lua))
7986
}
8087
}
8188

src/conversion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ impl FromLua for BString {
645645
match value {
646646
Value::String(s) => Ok((*s.as_bytes()).into()),
647647
#[cfg(feature = "luau")]
648-
Value::Buffer(buf) => unsafe { Ok(buf.as_slice().into()) },
648+
Value::Buffer(buf) => Ok(buf.to_vec().into()),
649649
_ => Ok((*lua
650650
.coerce_string(value)?
651651
.ok_or_else(|| Error::FromLuaConversionError {

src/serde/de.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,10 @@ impl<'de> serde::Deserializer<'de> for Deserializer {
165165
serde_userdata(ud, |value| value.deserialize_any(visitor))
166166
}
167167
#[cfg(feature = "luau")]
168-
Value::Buffer(buf) => visitor.visit_bytes(unsafe { buf.as_slice() }),
168+
Value::Buffer(buf) => {
169+
let lua = buf.0.lua.lock();
170+
visitor.visit_bytes(buf.as_slice(&lua))
171+
}
169172
Value::Function(_)
170173
| Value::Thread(_)
171174
| Value::UserData(_)

0 commit comments

Comments
 (0)