diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2011-11-05 23:30:46 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2011-11-05 23:30:46 +0900 |
| commit | d45d854926486e5f2655e1447be537f8fbdcac77 (patch) | |
| tree | cc2fe6db1926bfa760ba510692a5e65669578a02 /src | |
| parent | 17a1b51a76515a554c33941e6bf75cca89b4877a (diff) | |
Rewritten base64::decode and base64::encode
Diffstat (limited to 'src')
| -rw-r--r-- | src/HttpRequest.cc | 20 | ||||
| -rw-r--r-- | src/HttpResponse.cc | 2 | ||||
| -rw-r--r-- | src/HttpServer.cc | 3 | ||||
| -rw-r--r-- | src/Makefile.am | 2 | ||||
| -rw-r--r-- | src/RpcMethodImpl.cc | 8 | ||||
| -rw-r--r-- | src/XmlRpcRequestParserStateImpl.cc | 3 | ||||
| -rw-r--r-- | src/base64.cc | 208 | ||||
| -rw-r--r-- | src/base64.h | 180 | ||||
| -rw-r--r-- | src/json.cc | 4 |
9 files changed, 155 insertions, 275 deletions
diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index a23197fb..731952ea 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -219,10 +219,10 @@ std::string HttpRequest::createRequest() builtinHds.push_back(getProxyAuthString()); } if(authConfig_) { - builtinHds.push_back - (std::make_pair("Authorization:", - strconcat("Basic ", - Base64::encode(authConfig_->getAuthText())))); + std::string authText = authConfig_->getAuthText(); + std::string val = "Basic "; + val += base64::encode(authText.begin(), authText.end()); + builtinHds.push_back(std::make_pair("Authorization:", val)); } if(getPreviousURI().size()) { builtinHds.push_back(std::make_pair("Referer:", getPreviousURI())); @@ -298,12 +298,12 @@ std::string HttpRequest::createProxyRequest() const std::pair<std::string, std::string> HttpRequest::getProxyAuthString() const { - return std::make_pair - ("Proxy-Authorization:", - strconcat("Basic ", - Base64::encode(strconcat(proxyRequest_->getUsername(), - ":", - proxyRequest_->getPassword())))); + std::string authText = proxyRequest_->getUsername(); + authText += ':'; + authText += proxyRequest_->getPassword(); + std::string val = "Basic "; + val += base64::encode(authText.begin(), authText.end()); + return std::make_pair("Proxy-Authorization:", val); } void HttpRequest::enableContentEncoding() diff --git a/src/HttpResponse.cc b/src/HttpResponse.cc index 6c67bc4c..59438d1a 100644 --- a/src/HttpResponse.cc +++ b/src/HttpResponse.cc @@ -416,7 +416,7 @@ void HttpResponse::getDigest(std::vector<Checksum>& result) const break; } util::lowercase(hashType); - digest = Base64::decode(digest); + digest = base64::decode(digest.begin(), digest.end()); if(!MessageDigest::supports(hashType) || MessageDigest::getDigestLength(hashType) != digest.size()) { continue; diff --git a/src/HttpServer.cc b/src/HttpServer.cc index 67e72993..d55c1e34 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -225,8 +225,7 @@ bool HttpServer::authenticate() A2_AUTHMETHOD, vend(A2_AUTHMETHOD)-1)) { return false; } - std::string userpass = Base64::decode(std::string(p.second.first, - p.second.second)); + std::string userpass = base64::decode(p.second.first, p.second.second); std::pair<Sip, Sip> up; util::divide(up, userpass.begin(), userpass.end(), ':'); return util::streq(up.first.first, up.first.second, diff --git a/src/Makefile.am b/src/Makefile.am index 34b91058..8549b622 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,7 +48,7 @@ SRCS = Socket.h\ DefaultDiskWriterFactory.cc DefaultDiskWriterFactory.h\ File.cc File.h\ Option.cc Option.h\ - base64.cc base64.h\ + base64.h\ base32.cc base32.h\ LogFactory.cc LogFactory.h\ TimerA2.cc TimerA2.h\ diff --git a/src/RpcMethodImpl.cc b/src/RpcMethodImpl.cc index c152b8df..73453b6f 100644 --- a/src/RpcMethodImpl.cc +++ b/src/RpcMethodImpl.cc @@ -271,7 +271,9 @@ SharedHandle<ValueBase> AddTorrentRpcMethod::process SharedHandle<String> tempTorrentParam; if(req.jsonRpc) { - tempTorrentParam = String::g(Base64::decode(torrentParam->s())); + tempTorrentParam = String::g + (base64::decode(torrentParam->s().begin(), + torrentParam->s().end())); torrentParam = tempTorrentParam.get(); } std::vector<std::string> uris; @@ -317,7 +319,9 @@ SharedHandle<ValueBase> AddMetalinkRpcMethod::process SharedHandle<String> tempMetalinkParam; if(req.jsonRpc) { - tempMetalinkParam = String::g(Base64::decode(metalinkParam->s())); + tempMetalinkParam = String::g + (base64::decode(metalinkParam->s().begin(), + metalinkParam->s().end())); metalinkParam = tempMetalinkParam.get(); } SharedHandle<Option> requestOption(new Option(*e->getOption())); diff --git a/src/XmlRpcRequestParserStateImpl.cc b/src/XmlRpcRequestParserStateImpl.cc index 7711cddd..17a72681 100644 --- a/src/XmlRpcRequestParserStateImpl.cc +++ b/src/XmlRpcRequestParserStateImpl.cc @@ -238,7 +238,8 @@ void Base64XmlRpcRequestParserState::endElement const std::string& name, const std::string& characters) { - stm->setCurrentFrameValue(String::g(Base64::decode(characters))); + stm->setCurrentFrameValue + (String::g(base64::decode(characters.begin(), characters.end()))); } // StructXmlRpcRequestParserState diff --git a/src/base64.cc b/src/base64.cc deleted file mode 100644 index 3bcc82f7..00000000 --- a/src/base64.cc +++ /dev/null @@ -1,208 +0,0 @@ -/* <!-- copyright */ -/* - * aria2 - The high speed download utility - * - * Copyright (C) 2006 Tatsuhiro Tsujikawa - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * In addition, as a special exception, the copyright holders give - * permission to link the code of portions of this program with the - * OpenSSL library under certain conditions as described in each - * individual source file, and distribute linked combinations - * including the two. - * You must obey the GNU General Public License in all respects - * for all of the code used other than OpenSSL. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you - * do not wish to do so, delete this exception statement from your - * version. If you delete this exception statement from all source - * files in the program, then also delete it here. - */ -/* copyright --> */ -#include "base64.h" - -namespace aria2 { - -namespace { -const char CHAR_TABLE[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/', -}; -} // namespace - -namespace { -const int INDEX_TABLE[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 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, -1, -1, -1, -1, -1, - -1, 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, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -}; -} // namespace - -void Base64::encode(unsigned char*& result, size_t& rlength, - const unsigned char* src, size_t slength) -{ - if(slength == 0) { - rlength = 0; - return; - } - size_t trituple = (slength+2)/3; - int r = slength%3; - rlength = trituple*4; - result = new unsigned char[rlength]; - - unsigned char* p = result; - const unsigned char* s = src; - const unsigned char* smax = s+slength-r; - while(s != smax) { - int n = *s++ << 16; - n += *s++ << 8; - n += *s++; - *p++ = CHAR_TABLE[n >> 18]; - *p++ = CHAR_TABLE[n >> 12&0x3fu]; - *p++ = CHAR_TABLE[n >> 6&0x3fu]; - *p++ = CHAR_TABLE[n&0x3fu]; - } - if(r == 2) { - int n = *s++ << 16; - n += *s++ << 8; - *p++ = CHAR_TABLE[n >> 18]; - *p++ = CHAR_TABLE[n >> 12&0x3fu]; - *p++ = CHAR_TABLE[n >> 6&0x3fu]; - *p++ = '='; - } else if(r == 1) { - int n = *s++ << 16; - *p++ = CHAR_TABLE[n >> 18]; - *p++ = CHAR_TABLE[n >> 12&0x3fu]; - *p++ = '='; - *p++ = '='; - } -} - -void Base64::removeNonBase64Chars(unsigned char*& nsrc, - size_t& nlength, - const unsigned char* src, - size_t slength) -{ - unsigned char* temp = new unsigned char[slength]; - const unsigned char* end = src+slength; - size_t n = 0; - for(const unsigned char*s = src; s != end; ++s) { - if(INDEX_TABLE[*s] != -1 || *s == '=') { - *(temp+n++) = *s; - } - } - nlength = n; - nsrc = temp; -} - -void Base64::decode(unsigned char*& result, size_t& rlength, - const unsigned char* src, size_t slength) -{ - if(slength == 0) { - rlength = 0; - return; - } - unsigned char* nsrc; - size_t nlength; - removeNonBase64Chars(nsrc, nlength, src, slength); - - if(nlength%4 != 0) { - delete [] nsrc; - rlength = 0; - return; - } - - size_t quadtuple = nlength/4; - size_t len; - if(nsrc[nlength-1] == '=') { - if(nsrc[nlength-2] == '=') { - len = nlength-2; - } else { - len = nlength-1; - } - } else { - len = nlength; - } - rlength = len-quadtuple; - result = new unsigned char[rlength]; - int r = len%4; - - unsigned char* p = result; - const unsigned char* s = nsrc; - const unsigned char* smax = s+len-r; - while(s != smax) { - int n = INDEX_TABLE[*s++] << 18; - n += INDEX_TABLE[*s++] << 12; - n += INDEX_TABLE[*s++] << 6; - n += INDEX_TABLE[*s++]; - *p++ = n >> 16; - *p++ = n >> 8&0xffu; - *p++ = n&0xffu; - } - if(r == 2) { - int n = INDEX_TABLE[*s++] << 18; - n += INDEX_TABLE[*s++] << 12; - *p++ = n >> 16; - } else if(r == 3) { - int n = INDEX_TABLE[*s++] << 18; - n += INDEX_TABLE[*s++] << 12; - n += INDEX_TABLE[*s++] << 6; - *p++ = n >> 16; - *p++ = n >> 8&0xffu; - } - delete [] nsrc; -} - -std::string Base64::encode(const std::string& s) -{ - unsigned char* buf = 0; - size_t len; - encode(buf, len, s.c_str(), s.size()); - std::string r(&buf[0], &buf[len]); - delete [] buf; - return r; -} - -std::string Base64::decode(const std::string& s) -{ - unsigned char* buf = 0; - size_t len; - decode(buf, len, s.c_str(), s.size()); - std::string r(&buf[0], &buf[len]); - delete [] buf; - return r; -} - -} // namespace aria2 diff --git a/src/base64.h b/src/base64.h index 660510a4..b2e08660 100644 --- a/src/base64.h +++ b/src/base64.h @@ -2,7 +2,7 @@ /* * aria2 - The high speed download utility * - * Copyright (C) 2006 Tatsuhiro Tsujikawa + * Copyright (C) 2011 Tatsuhiro Tsujikawa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,63 +34,147 @@ /* copyright --> */ #ifndef D_BASE64_H #define D_BASE64_H + #include <string> namespace aria2 { -class Base64 -{ -private: - /** - * Removes non base64 chars(including '=') from src, and results are - * stored in nsrc and its length is stored in nlength. - * Caller must delete nsrc. - */ - static void removeNonBase64Chars(unsigned char*& nsrc, size_t& nlength, - const unsigned char* src, size_t slength); - -public: - /** - * Encods src whose length is slength into base64 encoded data - * and stores them to result. - * result is allocated in this function and the length is stored to rlength. - * If slength is equal to 0, then return with rlength set to 0 and result - * is left untouched. - * A caller must deallocate the memory used by result. - */ - static void encode(unsigned char*& result, size_t& rlength, - const unsigned char* src, size_t slength); +namespace base64 { - static void encode(unsigned char*& result, size_t& rlength, - const char* src, size_t slength) - { - encode(result, rlength, reinterpret_cast<const unsigned char*>(src), - slength); +template<typename InputIterator> +std::string encode(InputIterator first, InputIterator last) +{ + static const char CHAR_TABLE[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', + }; + std::string res; + size_t len = last-first; + if(len == 0) { + return res; } + size_t r = len%3; + InputIterator j = last-r; + while(first != j) { + int n = static_cast<unsigned char>(*first++) << 16; + n += static_cast<unsigned char>(*first++) << 8; + n += static_cast<unsigned char>(*first++); + res += CHAR_TABLE[n >> 18]; + res += CHAR_TABLE[(n >> 12) & 0x3fu]; + res += CHAR_TABLE[(n >> 6) & 0x3fu]; + res += CHAR_TABLE[n & 0x3fu]; + } + if(r == 2) { + int n = static_cast<unsigned char>(*first++) << 16; + n += static_cast<unsigned char>(*first++) << 8; + res += CHAR_TABLE[n >> 18]; + res += CHAR_TABLE[(n >> 12) & 0x3fu]; + res += CHAR_TABLE[(n >> 6) & 0x3fu]; + res += '='; + } else if(r == 1) { + int n = static_cast<unsigned char>(*first++) << 16; + res += CHAR_TABLE[n >> 18]; + res += CHAR_TABLE[(n >> 12) & 0x3fu]; + res += '='; + res += '='; + } + return res; +} - static std::string encode(const std::string& s); - - /** - * Dencods base64 encoded src whose length is slength and stores them to - * result. - * result is allocated in this function and the length is stored to rlength. - * If slength is equal to 0 or is not multiple of 4, then return with rlength - * set to 0 and result is left untouched. - * The function removes non-base64 characters before decoding. - * A caller must deallocate the memory used by result. - */ - static void decode(unsigned char*& result, size_t& rlength, - const unsigned char* src, size_t slength); +template<typename InputIterator> +InputIterator getNext +(InputIterator first, + InputIterator last, + const int* tbl) +{ + for(; first != last; ++first) { + if(tbl[static_cast<size_t>(*first)] != -1 || *first == '=') { + break; + } + } + return first; +} - static void decode(unsigned char*& result, size_t& rlength, - const char* src, size_t slength) - { - decode(result, rlength, reinterpret_cast<const unsigned char*>(src), - slength); +template<typename InputIterator> +std::string decode(InputIterator first, InputIterator last) +{ + static const int INDEX_TABLE[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 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, -1, -1, -1, -1, -1, + -1, 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, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + std::string res; + InputIterator k[5]; + int eq = 0; + for(; first != last;) { + for(int i = 1; i <= 4; ++i) { + k[i] = getNext(first, last, INDEX_TABLE); + if(k[i] == last) { + res.clear(); + return res; + } else if(*k[i] == '=' && eq == 0) { + eq = i; + } + first = k[i]+1; + } + if(eq) { + break; + } + int n = (INDEX_TABLE[static_cast<unsigned char>(*k[1])] << 18)+ + (INDEX_TABLE[static_cast<unsigned char>(*k[2])] << 12)+ + (INDEX_TABLE[static_cast<unsigned char>(*k[3])] << 6)+ + INDEX_TABLE[static_cast<unsigned char>(*k[4])]; + res += n >> 16; + res += n >> 8 & 0xffu; + res += n & 0xffu; + } + if(eq) { + if(eq <= 2) { + res.clear(); + return res; + } else { + for(int i = eq; i <= 4; ++i) { + if(*k[i] != '=') { + res.clear(); + return res; + } + } + if(eq == 3) { + int n = (INDEX_TABLE[static_cast<unsigned char>(*k[1])] << 18)+ + (INDEX_TABLE[static_cast<unsigned char>(*k[2])] << 12); + res += n >> 16; + } else if(eq == 4) { + int n = (INDEX_TABLE[static_cast<unsigned char>(*k[1])] << 18)+ + (INDEX_TABLE[static_cast<unsigned char>(*k[2])] << 12)+ + (INDEX_TABLE[static_cast<unsigned char>(*k[3])] << 6); + res += n >> 16; + res += n >> 8 & 0xffu; + } + } } + return res; +} - static std::string decode(const std::string& s); -}; +} // namespace base64 } // namespace aria2 diff --git a/src/json.cc b/src/json.cc index 391d2a88..825d5905 100644 --- a/src/json.cc +++ b/src/json.cc @@ -646,8 +646,8 @@ decodeGetParams(const std::string& query) callback.assign((*i).first+13, (*i).second); } } - std::string jsonParam = - Base64::decode(util::percentDecode(params.first, params.second)); + std::string decparam = util::percentDecode(params.first, params.second); + std::string jsonParam = base64::decode(decparam.begin(), decparam.end()); if(method.first == method.second && id.first == id.second) { // Assume batch call. jsonRequest = jsonParam; |
