diff --git a/indra/llcommon/llbase64.cpp b/indra/llcommon/llbase64.cpp index a0fb7985cebe0201f1359e57455ee23bbe7c1c4a..22bacaf1f4b5197622b0abb7f2d64984099c0f62 100755 --- a/indra/llcommon/llbase64.cpp +++ b/indra/llcommon/llbase64.cpp @@ -104,3 +104,75 @@ size_t LLBase64::requiredDecryptionSpace(const std::string& str) return len * 0.75 - padding; } +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +static const U8 apr_pr2six[256] = +{ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +}; + +size_t LLBase64::apr_base64_decode_binary(U8 *bufplain, const char* bufcoded) +{ + size_t nbytesdecoded, nprbytes; + const U8 *bufin; + U8 *bufout; + + bufin = (const U8*) bufcoded; + while (apr_pr2six[*(bufin++)] <= 63); + nprbytes = (bufin - (const U8 *) bufcoded) - 1; + nbytesdecoded = (((size_t)nprbytes + 3) / 4) * 3; + + bufout = (U8 *) bufplain; + bufin = (const U8 *) bufcoded; + + while (nprbytes > 4) { + *(bufout++) = (U8) (apr_pr2six[*bufin] << 2 | apr_pr2six[bufin[1]] >> 4); + *(bufout++) = (U8) (apr_pr2six[bufin[1]] << 4 | apr_pr2six[bufin[2]] >> 2); + *(bufout++) = (U8) (apr_pr2six[bufin[2]] << 6 | apr_pr2six[bufin[3]]); + bufin += 4; + nprbytes -= 4; + } + + /* Note: (nprbytes == 1) would be an error, so just ingore that case */ + if (nprbytes > 1) { + *(bufout++) = (U8) (apr_pr2six[*bufin] << 2 | apr_pr2six[bufin[1]] >> 4); + } + if (nprbytes > 2) { + *(bufout++) = (U8) (apr_pr2six[bufin[1]] << 4 | apr_pr2six[bufin[2]] >> 2); + } + if (nprbytes > 3) { + *(bufout++) = (U8) (apr_pr2six[bufin[2]] << 6 | apr_pr2six[bufin[3]]); + } + + nbytesdecoded -= (4 - (size_t)nprbytes) & 3; + return nbytesdecoded; +} diff --git a/indra/llcommon/llbase64.h b/indra/llcommon/llbase64.h index 064da10a1f4d348fdd1873e383eaa4f9e45ee53f..9c84139fd26de456256e47ecc4fd968b56710bfa 100755 --- a/indra/llcommon/llbase64.h +++ b/indra/llcommon/llbase64.h @@ -36,6 +36,9 @@ public: static size_t decode(const std::string& input, U8 * buffer, size_t buffer_size); static std::string decode(const std::string& input); static size_t requiredDecryptionSpace(const std::string& str); + + // *HACK: Special case because of OpenSSL ASCII/EBCDIC issues + static size_t apr_base64_decode_binary(U8 *bufplain, const char* bufcoded); }; #endif diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 1c46f0d22fa2ebcd24e24268daf8f15ce9d092e9..210e0befcdd7bd0837fce35676b025301d057e55 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -64,9 +64,6 @@ #include "llviewernetwork.h" #include "llnotificationsutil.h" -// for base64 decoding -#include "apr_base64.h" - #define USE_SESSION_GROUPS 0 extern LLMenuBarGL* gMenuBarView; @@ -4479,8 +4476,8 @@ bool LLVivoxVoiceClient::IDFromName(const std::string inName, LLUUID &uuid) LLStringUtil::replaceChar(temp, '-', '+'); LLStringUtil::replaceChar(temp, '_', '/'); - U8 rawuuid[UUID_BYTES + 1]; - int len = apr_base64_decode_binary(rawuuid, temp.c_str() + 1); + U8 rawuuid[UUID_BYTES + 1]; + int len = LLBase64::apr_base64_decode_binary(rawuuid, temp.c_str() + 1); if(len == UUID_BYTES) { // The decode succeeded. Stuff the bits into the result's UUID