From 3e4f4208b2331c09495d6803bce03a233e6315b5 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 11 May 2024 14:09:08 +0100 Subject: [PATCH] improve broken llBase64ToInteger --- .../Shared/Api/Implementation/LSL_Api.cs | 76 +++++++++---------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index efcf32fb99..16b13ad225 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -12047,8 +12047,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // redundancy). // // - // LSL requires a base64 string to be 8 - // characters in length. LSL also uses '/' + // LSL also uses '/' // rather than '-' (MIME compliant). // // @@ -12060,6 +12059,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // these functions, so the string to integer // conversion returns '0' if an invalid // character is encountered during conversion. + // Only full bytes are considered, partial are counted as 0 // // // References @@ -12213,59 +12213,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llBase64ToInteger(string str) { - int number = 0; - int digit; - - - // Require a well-fromed base64 string - - if (str.Length > 8) + if (str is null || str.Length < 2 || str.Length > 8) return 0; - // The loop is unrolled in the interests - // of performance and simple necessity. - // - // MUST find 6 digits to be well formed - // -1 == invalid - // 0 == padding - + int digit; if ((digit = c2itable[str[0]]) <= 0) - { - return digit < 0 ? (int)0 : number; - } - number += --digit<<26; + return 0; + + int number = --digit << 26; if ((digit = c2itable[str[1]]) <= 0) - { - return digit < 0 ? (int)0 : number; - } - number += --digit<<20; + return 0; + + if (str.Length == 2) + return number | (--digit & 0x30) << 20; + + int next = --digit << 20; if ((digit = c2itable[str[2]]) <= 0) - { - return digit < 0 ? (int)0 : number; - } - number += --digit<<14; + return number; + + number |= next; + if (str.Length == 3) + return number | (--digit & 0x3C) << 14; + + next = --digit << 14; if ((digit = c2itable[str[3]]) <= 0) - { - return digit < 0 ? (int)0 : number; - } - number += --digit<<8; + return number; + + number |= next; + number |= --digit << 8; + if (str.Length == 4) + return number; if ((digit = c2itable[str[4]]) <= 0) - { - return digit < 0 ? (int)0 : number; - } - number += --digit<<2; + return number; + + if (str.Length == 5) + return number; + + next = --digit << 2; if ((digit = c2itable[str[5]]) <= 0) - { - return digit < 0 ? (int)0 : number; - } - number += --digit>>4; + return number; - // ignore trailing padding + number |= next; + number |= --digit >> 4; return number; }