From 3f105e5782d7d2fec4d55065cf13ba6be1de66c8 Mon Sep 17 00:00:00 2001 From: Xurkon Date: Sat, 6 Jun 2026 07:03:16 -0500 Subject: [PATCH] fix: harden learner compatibility shims --- Modules/Libs/QuestieLoader.lua | 45 ++++++++++++++++++++++++++++++++++ Modules/QuestieLearner.lua | 36 ++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/Modules/Libs/QuestieLoader.lua b/Modules/Libs/QuestieLoader.lua index ec5e0df..b4205e8 100644 --- a/Modules/Libs/QuestieLoader.lua +++ b/Modules/Libs/QuestieLoader.lua @@ -146,6 +146,51 @@ if not string.gmatch then string.gmatch = string.gfind end +-- Shim for Lua 5.0 / older clients where string.trim is not available. +-- Supports trimming either whitespace or a custom set of leading/trailing chars. +if not string.trim then + local defaultTrimChars = { + [" "] = true, + ["\t"] = true, + ["\r"] = true, + ["\n"] = true, + } + + local function buildTrimSet(chars) + local set = {} + if not chars or chars == "" then + for ch in pairs(defaultTrimChars) do + set[ch] = true + end + return set + end + for i = 1, string.len(chars) do + set[string.sub(chars, i, i)] = true + end + return set + end + + string.trim = function(text, chars) + if text == nil then return nil end + text = tostring(text) + local trimSet = buildTrimSet(chars) + local startPos = 1 + local endPos = string.len(text) + + while startPos <= endPos and trimSet[string.sub(text, startPos, startPos)] do + startPos = startPos + 1 + end + while endPos >= startPos and trimSet[string.sub(text, endPos, endPos)] do + endPos = endPos - 1 + end + + if startPos > endPos then + return "" + end + return string.sub(text, startPos, endPos) + end +end + -- Shim for Lua 5.0 where select() was not yet implemented. -- Fix #7: The original used a `while n > 0` loop that never decremented n, -- making the loop body run exactly once before returning. Use a plain diff --git a/Modules/QuestieLearner.lua b/Modules/QuestieLearner.lua index cf6fa26..25fbb1a 100644 --- a/Modules/QuestieLearner.lua +++ b/Modules/QuestieLearner.lua @@ -30,6 +30,40 @@ local type = type local tostring = tostring local tonumber = tonumber local string_trim = string.trim +if not string_trim then + local whitespace = { + [" "] = true, + ["\t"] = true, + ["\r"] = true, + ["\n"] = true, + } + string_trim = function(text, chars) + if text == nil then return nil end + text = tostring(text) + local trimSet = {} + if not chars or chars == "" then + for ch in pairs(whitespace) do + trimSet[ch] = true + end + else + for i = 1, string.len(chars) do + trimSet[string.sub(chars, i, i)] = true + end + end + local startPos = 1 + local endPos = string.len(text) + while startPos <= endPos and trimSet[string.sub(text, startPos, startPos)] do + startPos = startPos + 1 + end + while endPos >= startPos and trimSet[string.sub(text, endPos, endPos)] do + endPos = endPos - 1 + end + if startPos > endPos then + return "" + end + return string.sub(text, startPos, endPos) + end +end local string_sub = string.sub local string_len = string.len local string_upper = string.upper @@ -2182,7 +2216,7 @@ function QuestieLearner:Sanitize(data) -- Trim name/text strings if data[1] and type(data[1]) == "string" then - data[1] = string.trim(data[1]) + data[1] = string_trim(data[1]) end return data