llbase64.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /**
  2. * @file llbase64.cpp
  3. *
  4. * $LicenseInfo:firstyear=2007&license=viewergpl$
  5. * See below for the Apache license applicable to part of the code.
  6. *
  7. * Copyright (c) 2004 Apache Foundation (for parts borrowed from APR-util),
  8. * (c) 2007-2009, Linden Research, Inc.
  9. * (c) 2009-2023, Henri Beauchamp.
  10. *
  11. * Second Life Viewer Source Code
  12. * The source code in this file ("Source Code") is provided by Linden Lab
  13. * to you under the terms of the GNU General Public License, version 2.0
  14. * ("GPL"), unless you have obtained a separate licensing agreement
  15. * ("Other License"), formally executed by you and Linden Lab. Terms of
  16. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18. *
  19. * There are special exceptions to the terms and conditions of the GPL as
  20. * it is applied to this Source Code. View the full text of the exception
  21. * in the file doc/FLOSS-exception.txt in this software distribution, or
  22. * online at
  23. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24. *
  25. * By copying, modifying or distributing this software, you acknowledge
  26. * that you have read and understood your obligations described above,
  27. * and agree to abide by those obligations.
  28. *
  29. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31. * COMPLETENESS OR PERFORMANCE.
  32. * $/LicenseInfo$
  33. */
  34. #include "linden_common.h"
  35. #include "llbase64.h"
  36. ///////////////////////////////////////////////////////////////////////////////
  37. // This is the APR-util libary code for apr_base64_*() functions, slightly
  38. // ammended by me (HB). Since these functions are the only ones we have ever
  39. // used in the viewer code, there is no point in using the APR-util library
  40. // just for them. This part of the code is therefore under the Apache license:
  41. //
  42. // Licensed to the Apache Software Foundation (ASF) under one or more
  43. // contributor license agreements. See the NOTICE file distributed with
  44. // this work for additional information regarding copyright ownership.
  45. // The ASF licenses this file to You under the Apache License, Version 2.0
  46. // (the "License"); you may not use this file except in compliance with
  47. // the License. You may obtain a copy of the License at
  48. // http://www.apache.org/licenses/LICENSE-2.0
  49. //
  50. // Unless required by applicable law or agreed to in writing, software
  51. // distributed under the License is distributed on an "AS IS" BASIS,
  52. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  53. // See the License for the specific language governing permissions and
  54. // limitations under the License.
  55. static const unsigned char pr2six[256] =
  56. {
  57. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  58. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  59. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
  60. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
  61. 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  62. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
  63. 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  64. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
  65. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  66. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  67. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  68. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  69. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  70. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  71. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  72. 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
  73. };
  74. static const char basis_64[] =
  75. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  76. //static
  77. size_t LLBase64::decodeLen(const char* input)
  78. {
  79. const unsigned char* bin = (const unsigned char*)input;
  80. while (pr2six[*(bin++)] <= 63) ;
  81. size_t nprbytes = (bin - (const unsigned char*)input) - 1;
  82. return ((nprbytes + 3) / 4) * 3 + 1;
  83. }
  84. //static
  85. size_t LLBase64::decode(unsigned char* output, const char* input)
  86. {
  87. const unsigned char* bin = (const unsigned char*)input;
  88. while (pr2six[*(bin++)] <= 63) ;
  89. size_t nprbytes = (bin - (const unsigned char*)input) - 1;
  90. size_t nbytesdecoded = ((nprbytes + 3) / 4) * 3;
  91. unsigned char* bout = (unsigned char*)output;
  92. bin = (const unsigned char*)input;
  93. while (nprbytes > 4)
  94. {
  95. *(bout++) = (unsigned char)(pr2six[*bin] << 2 | pr2six[bin[1]] >> 4);
  96. *(bout++) = (unsigned char)(pr2six[bin[1]] << 4 | pr2six[bin[2]] >> 2);
  97. *(bout++) = (unsigned char)(pr2six[bin[2]] << 6 | pr2six[bin[3]]);
  98. bin += 4;
  99. nprbytes -= 4;
  100. }
  101. // Note: (nprbytes == 1) would be an error, so just ingore that case.
  102. if (nprbytes > 1)
  103. {
  104. *(bout++) = (unsigned char)(pr2six[*bin] << 2 | pr2six[bin[1]] >> 4);
  105. }
  106. if (nprbytes > 2)
  107. {
  108. *(bout++) = (unsigned char)(pr2six[bin[1]] << 4 | pr2six[bin[2]] >> 2);
  109. }
  110. if (nprbytes > 3)
  111. {
  112. *(bout++) = (unsigned char)(pr2six[bin[2]] << 6 | pr2six[bin[3]]);
  113. }
  114. nbytesdecoded -= (4 - nprbytes) & 3;
  115. return nbytesdecoded;
  116. }
  117. //static
  118. size_t LLBase64::encode(char* output, const unsigned char* input, size_t len)
  119. {
  120. size_t i;
  121. char* p = output;
  122. for (i = 0; i + 2 < len; i += 3)
  123. {
  124. *p++ = basis_64[(input[i] >> 2) & 0x3F];
  125. *p++ = basis_64[((input[i] & 0x3) << 4) |
  126. ((int)(input[i + 1] & 0xF0) >> 4)];
  127. *p++ = basis_64[((input[i + 1] & 0xF) << 2) |
  128. ((int)(input[i + 2] & 0xC0) >> 6)];
  129. *p++ = basis_64[input[i + 2] & 0x3F];
  130. }
  131. if (i < len)
  132. {
  133. *p++ = basis_64[(input[i] >> 2) & 0x3F];
  134. if (i == (len - 1))
  135. {
  136. *p++ = basis_64[((input[i] & 0x3) << 4)];
  137. *p++ = '=';
  138. }
  139. else
  140. {
  141. *p++ = basis_64[((input[i] & 0x3) << 4) |
  142. ((int)(input[i + 1] & 0xF0) >> 4)];
  143. *p++ = basis_64[((input[i + 1] & 0xF) << 2)];
  144. }
  145. *p++ = '=';
  146. }
  147. *p++ = '\0';
  148. return p - output;
  149. }
  150. ///////////////////////////////////////////////////////////////////////////////
  151. // GPL-licensed part
  152. //static
  153. std::string LLBase64::encode(const char* input, size_t input_size)
  154. {
  155. std::string output;
  156. if (input && input_size > 0)
  157. {
  158. // Estimated (maximum) length, trailing nul char included
  159. size_t b64_buffer_length = encodeLen(input_size);
  160. char* b64_buffer = new char[b64_buffer_length];
  161. encode(b64_buffer, (const unsigned char*)input, input_size);
  162. output.assign(b64_buffer); // Note: buffer is nul-terminated
  163. delete[] b64_buffer;
  164. }
  165. return output;
  166. }
  167. //static
  168. std::string LLBase64::decode(const char* input)
  169. {
  170. std::string output;
  171. if (input)
  172. {
  173. // Estimated (maximum) length
  174. size_t b64_buffer_length = decodeLen(input);
  175. unsigned char* b64_buffer = new unsigned char[b64_buffer_length];
  176. // Actual length
  177. b64_buffer_length = decode(b64_buffer, input);
  178. output.assign((char*)b64_buffer, b64_buffer_length);
  179. delete[] b64_buffer;
  180. }
  181. return output;
  182. }