diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a259a85a7b..e7ff2578f6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -11093,107 +11093,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public LSL_String llXorBase64Strings(string str1, string str2) - { - int padding = 0; - - string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - ScriptSleep(300); - m_host.AddScriptLPS(1); - - if (str1 == String.Empty) - return String.Empty; - if (str2 == String.Empty) - return str1; - - int len = str2.Length; - if ((len % 4) != 0) // LL is EVIL!!!! - { - while (str2.EndsWith("=")) - str2 = str2.Substring(0, str2.Length - 1); - - len = str2.Length; - int mod = len % 4; - - if (mod == 1) - str2 = str2.Substring(0, str2.Length - 1); - else if (mod == 2) - str2 += "=="; - else if (mod == 3) - str2 += "="; - } - - byte[] data1; - byte[] data2; - try - { - data1 = Convert.FromBase64String(str1); - data2 = Convert.FromBase64String(str2); - } - catch (Exception) - { - return new LSL_String(String.Empty); - } - - // For cases where the decoded length of s2 is greater - // than the decoded length of s1, simply perform a normal - // decode and XOR - // - /* - if (data2.Length >= data1.Length) - { - for (int pos = 0 ; pos < data1.Length ; pos++ ) - data1[pos] ^= data2[pos]; - - return Convert.ToBase64String(data1); - } - */ - - // Remove padding - while (str1.EndsWith("=")) - { - str1 = str1.Substring(0, str1.Length - 1); - padding++; - } - while (str2.EndsWith("=")) - str2 = str2.Substring(0, str2.Length - 1); - - byte[] d1 = new byte[str1.Length]; - byte[] d2 = new byte[str2.Length]; - - for (int i = 0 ; i < str1.Length ; i++) - { - int idx = b64.IndexOf(str1.Substring(i, 1)); - if (idx == -1) - idx = 0; - d1[i] = (byte)idx; - } - - for (int i = 0 ; i < str2.Length ; i++) - { - int idx = b64.IndexOf(str2.Substring(i, 1)); - if (idx == -1) - idx = 0; - d2[i] = (byte)idx; - } - - string output = String.Empty; - - for (int pos = 0 ; pos < d1.Length ; pos++) - output += b64[d1[pos] ^ d2[pos % d2.Length]]; - - // Here's a funny thing: LL blithely violate the base64 - // standard pretty much everywhere. Here, padding is - // added only if the first input string had it, rather - // than when the data actually needs it. This can result - // in invalid base64 being returned. Go figure. - - while (padding-- > 0) - output += "="; - - return output; - } public void llRemoteDataSetRegion() { @@ -14114,13 +14013,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return (int)estate.GetRegionFlags(); } - public LSL_String llXorBase64StringsCorrect(string str1, string str2) + private const string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + public LSL_String llXorBase64Strings(string str1, string str2) { + int padding = 0; + + ScriptSleep(300); m_host.AddScriptLPS(1); - if (str1 == String.Empty) - return String.Empty; - if (str2 == String.Empty) + if (str1 == string.Empty) + return string.Empty; + if (str2 == string.Empty) return str1; int len = str2.Length; @@ -14140,6 +14044,88 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api str2 += "="; } + byte[] data1; + byte[] data2; + try + { + data1 = Convert.FromBase64String(str1); + data2 = Convert.FromBase64String(str2); + } + catch + { + return string.Empty; + } + + // Remove padding + while (str1.EndsWith("=")) + { + str1 = str1.Substring(0, str1.Length - 1); + padding++; + } + while (str2.EndsWith("=")) + str2 = str2.Substring(0, str2.Length - 1); + + byte[] d1 = new byte[str1.Length]; + byte[] d2 = new byte[str2.Length]; + + for (int i = 0; i < str1.Length; i++) + { + int idx = b64.IndexOf(str1.Substring(i, 1)); + if (idx == -1) + idx = 0; + d1[i] = (byte)idx; + } + + for (int i = 0; i < str2.Length; i++) + { + int idx = b64.IndexOf(str2.Substring(i, 1)); + if (idx == -1) + idx = 0; + d2[i] = (byte)idx; + } + + string output = string.Empty; + + for (int pos = 0; pos < d1.Length; pos++) + output += b64[d1[pos] ^ d2[pos % d2.Length]]; + + // Here's a funny thing: LL blithely violate the base64 + // standard pretty much everywhere. Here, padding is + // added only if the first input string had it, rather + // than when the data actually needs it. This can result + // in invalid base64 being returned. Go figure. + + while (padding-- > 0) + output += "="; + + return output; + } + + public LSL_String llXorBase64StringsCorrect(string str1, string str2) + { + m_host.AddScriptLPS(1); + + if (str1 == string.Empty) + return string.Empty; + if (str2 == string.Empty) + return str1; + + int len = str2.Length; + if ((len % 4) != 0) // LL is EVIL!!!! + { + str2.TrimEnd(new char[] { '=' }); + + len = str2.Length; + int mod = len % 4; + + if (mod == 1) + str2 = str2.Substring(0, str2.Length - 1); + else if (mod == 2) + str2 += "=="; + else if (mod == 3) + str2 += "="; + } + byte[] data1; byte[] data2; try @@ -14178,6 +14164,83 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return Convert.ToBase64String(data1); } + private string truncateBase64(string input) + { + if (string.IsNullOrEmpty(input)) + return string.Empty; + + int paddingPos = -1; + for (int i = 0; i < input.Length; i++) + { + char c = input[i]; + if (c >= 'A' && c <= 'Z') + continue; + if (c >= 'a' && c <= 'z') + continue; + if (c >= '0' && c <= '9') + continue; + if (c == '+' || c == '/') + continue; + paddingPos = i; + break; + } + + if (paddingPos == 0) + return string.Empty; + + if (paddingPos > 0) + input = input.Substring(0, paddingPos); + + int remainder = input.Length % 4; + switch(remainder) + { + case 0: + return input; + case 1: + return input.Substring(0, input.Length - 1); + case 2: + return input + "=="; + } + return input + "="; + } + + public LSL_String llXorBase64(string str1, string str2) + { + m_host.AddScriptLPS(1); + + if (string.IsNullOrEmpty(str2)) + return str1; + + str1 = truncateBase64(str1); + if (string.IsNullOrEmpty(str1)) + return string.Empty; + + str2 = truncateBase64(str2); + if (string.IsNullOrEmpty(str2)) + return str1; + + byte[] data1; + byte[] data2; + try + { + data1 = Convert.FromBase64String(str1); + data2 = Convert.FromBase64String(str2); + } + catch (Exception) + { + return string.Empty; + } + + for (int pos = 0, pos2 = 0; pos < data1.Length; pos++) + { + data1[pos] ^= data2[pos2]; + if(++pos2 >= data2.Length) + pos2 = 0; + } + + return Convert.ToBase64String(data1); + } + public LSL_Key llHTTPRequest(string url, LSL_List parameters, string body) { m_host.AddScriptLPS(1);