@@ -12,6 +12,11 @@ use super::luacode::*;
1212
1313pub const LUA_RESUMEERROR : c_int = -1 ;
1414
15+ // Keep in sync with Bytecode.h
16+ const LBC_VERSION_MAX : u8 = 11 ;
17+ const LBC_TYPE_VERSION_MIN : u8 = 1 ;
18+ const LBC_TYPE_VERSION_MAX : u8 = 3 ;
19+
1520unsafe fn compat53_reverse ( L : * mut lua_State , mut a : c_int , mut b : c_int ) {
1621 while a < b {
1722 lua_pushvalue ( L , a) ;
@@ -368,6 +373,24 @@ pub unsafe fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_in
368373 }
369374}
370375
376+ // Detects whether a chunk is Luau bytecode or text source.
377+ pub unsafe fn luaL_isbytecode ( data : * const c_char , size : usize ) -> bool {
378+ if size == 0 {
379+ return false ;
380+ }
381+ match * data as u8 {
382+ b if b < b'\t' => true , // bytecode
383+ b if b <= LBC_VERSION_MAX => {
384+ let types_version = ( size >= 2 ) . then ( || * data. add ( 1 ) as u8 ) ;
385+ match types_version {
386+ Some ( LBC_TYPE_VERSION_MIN ..=LBC_TYPE_VERSION_MAX ) => true , // bytecode
387+ _ => false , // text
388+ }
389+ }
390+ _ => false , // text
391+ }
392+ }
393+
371394pub unsafe fn luaL_loadbufferenv (
372395 L : * mut lua_State ,
373396 data : * const c_char ,
@@ -384,19 +407,21 @@ pub unsafe fn luaL_loadbufferenv(
384407 free ( * ( data as * mut * mut c_char ) as * mut c_void ) ;
385408 }
386409
387- let chunk_is_text = size == 0 || ( * data as u8 ) >= b'\t' ;
410+ let is_bytecode = luaL_isbytecode ( data, size ) ;
388411 if !mode. is_null ( ) {
389412 let modeb = CStr :: from_ptr ( mode) . to_bytes ( ) ;
390- if !chunk_is_text && !modeb. contains ( & b'b' ) {
413+ let allow_binary = modeb. contains ( & b'b' ) ;
414+ let allow_text = modeb. contains ( & b't' ) ;
415+ if is_bytecode && !allow_binary {
391416 lua_pushfstring ( L , cstr ! ( "attempt to load a binary chunk (mode is '%s')" ) , mode) ;
392417 return LUA_ERRSYNTAX ;
393- } else if chunk_is_text && !modeb . contains ( & b't' ) {
418+ } else if !is_bytecode && !allow_text {
394419 lua_pushfstring ( L , cstr ! ( "attempt to load a text chunk (mode is '%s')" ) , mode) ;
395420 return LUA_ERRSYNTAX ;
396421 }
397422 }
398423
399- let status = if chunk_is_text {
424+ let status = if !is_bytecode {
400425 if env < 0 {
401426 env -= 1 ;
402427 }
0 commit comments