@@ -94,34 +94,48 @@ void AbstractServer::ResetConnectionCount() {
9494 unique_connections.clear ();
9595}
9696
97- static const std::string base64_chars =
98- " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
99- " abcdefghijklmnopqrstuvwxyz"
100- " 0123456789+/" ;
101- /* *
102- * Decodes the given BASE64 string to a normal string.
103- * Source: https://gist.github.com/williamdes/308b95ac9ef1ee89ae0143529c361d37
104- **/
105- std::string AbstractServer::Base64Decode (const std::string& in) {
106- std::string out;
10797
108- std::vector<int > T (256 , -1 );
109- for (size_t i = 0 ; i < 64 ; i++)
110- T[base64_chars[i]] = static_cast <int >(i);
98+ std::string AbstractServer::Base64Decode (const std::string& in) {
99+ static const unsigned char T[256 ] = []{
100+ unsigned char t[256 ];
101+ std::fill (std::begin (t), std::end (t), 0xFF );
102+ static const char base64_chars[] =
103+ " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
104+ " abcdefghijklmnopqrstuvwxyz"
105+ " 0123456789+/" ;
106+ for (int i = 0 ; i < 64 ; i++)
107+ t[static_cast <unsigned char >(base64_chars[i])] = i;
108+ return t;
109+ }();
110+
111+ size_t in_len = in.size ();
112+ if (in_len % 4 != 0 ) return {}; // invalid
113+
114+ size_t out_len = in_len / 4 * 3 ;
115+ if (in_len && in[in_len - 1 ] == ' =' ) out_len--;
116+ if (in_len > 1 && in[in_len - 2 ] == ' =' ) out_len--;
117+
118+ std::string out (out_len, ' \0 ' );
119+ size_t o = 0 ;
120+
121+ for (size_t i = 0 ; i < in_len; i += 4 ) {
122+ uint32_t n = (T[(unsigned char )in[i]] << 18 ) |
123+ (T[(unsigned char )in[i+1 ]] << 12 ) |
124+ (T[(unsigned char )in[i+2 ]] << 6 ) |
125+ (T[(unsigned char )in[i+3 ]]);
126+
127+ // we always write 3 bytes
128+ out[o++] = (n >> 16 ) & 0xFF ;
129+ out[o++] = (n >> 8 ) & 0xFF ;
130+ out[o++] = n & 0xFF ;
131+ }
111132
112- int val = 0 ;
113- int valb = -8 ;
114- for (unsigned char c : in) {
115- if (T[c] == -1 ) {
116- break ;
117- }
118- val = (val << 6 ) + T[c];
119- valb += 6 ;
120- if (valb >= 0 ) {
121- out.push_back (char ((val >> valb) & 0xFF ));
122- valb -= 8 ;
123- }
133+ // fix for padding '='
134+ if (in_len >= 2 ) {
135+ if (in[in_len - 1 ] == ' =' ) out.pop_back ();
136+ if (in[in_len - 2 ] == ' =' ) out.pop_back ();
124137 }
138+
125139 return out;
126140}
127141
0 commit comments