From 9f58414e99431a0fabfdfab067d228693f9a85bb Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Tue, 12 Mar 2024 23:12:05 +0100 Subject: [PATCH] Make parsing of _VERSION global more robust --- src/lune/globals/version.rs | 41 +++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/lune/globals/version.rs b/src/lune/globals/version.rs index 3f72b5c..4904144 100644 --- a/src/lune/globals/version.rs +++ b/src/lune/globals/version.rs @@ -1,24 +1,39 @@ use mlua::prelude::*; pub fn create(lua: &Lua) -> LuaResult> { + let lune_version = format!("Lune {}", env!("CARGO_PKG_VERSION")); + let luau_version_full = lua .globals() .get::<_, LuaString>("_VERSION") .expect("Missing _VERSION global"); + let luau_version_str = luau_version_full + .to_str() + .context("Invalid utf8 found in _VERSION global")?; - let luau_version = luau_version_full - .to_str()? - .strip_prefix("Luau 0.") - .expect("_VERSION global is formatted incorrectly") - .trim(); - - if luau_version.is_empty() { - panic!("_VERSION global is missing version number") + // If this function runs more than once, we + // may get an already formatted lune version. + if luau_version_str.starts_with(&lune_version) { + return Ok(luau_version_full); } - lua.create_string(format!( - "Lune {lune}+{luau}", - lune = env!("CARGO_PKG_VERSION"), - luau = luau_version, - )) + // Luau version is expected to be in the format "Luau 0.x" and sometimes "Luau 0.x.y" + if !luau_version_str.starts_with("Luau 0.") { + panic!("_VERSION global is formatted incorrectly\nGot: '{luau_version_str}'") + } + let luau_version = luau_version_str.strip_prefix("Luau 0.").unwrap().trim(); + + // We make some guarantees about the format of the _VERSION global, + // so make sure that the luau version also follows those rules. + if luau_version.is_empty() { + panic!("_VERSION global is missing version number\nGot: '{luau_version_str}'") + } else if !luau_version.chars().all(is_valid_version_char) { + panic!("_VERSION global contains invalid characters\nGot: '{luau_version_str}'") + } + + lua.create_string(format!("{lune_version}+{luau_version}")) +} + +fn is_valid_version_char(c: char) -> bool { + matches!(c, '0'..='9' | '.') }