From 118626afc47e290be1ae490f5be26523233ccb61 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 3 Nov 2011 19:27:29 +0900 Subject: [PATCH] util::percentDecode now takes iterators as arguments. --- src/FtpConnection.cc | 11 +++++++---- src/FtpNegotiationCommand.cc | 3 ++- src/HttpRequestCommand.cc | 3 ++- src/HttpResponse.cc | 4 +++- src/json.cc | 38 ++++++++++++++++++++++-------------- src/magnet.cc | 11 ++++++----- src/uri.cc | 4 ++-- src/util.cc | 25 ++++++++++++------------ src/util.h | 3 ++- test/UtilTest.cc | 17 ++++++++++------ 10 files changed, 71 insertions(+), 48 deletions(-) diff --git a/src/FtpConnection.cc b/src/FtpConnection.cc index ec6037c4..9da2b730 100644 --- a/src/FtpConnection.cc +++ b/src/FtpConnection.cc @@ -145,7 +145,7 @@ bool FtpConnection::sendCwd(const std::string& dir) { if(socketBuffer_.sendBufferIsEmpty()) { std::string request = "CWD "; - request += util::percentDecode(dir); + request += util::percentDecode(dir.begin(), dir.end()); request += "\r\n"; A2_LOG_INFO(fmt(MSG_SENDING_REQUEST, cuid_,request.c_str())); @@ -159,7 +159,8 @@ bool FtpConnection::sendMdtm() { if(socketBuffer_.sendBufferIsEmpty()) { std::string request = "MDTM "; - request += util::percentDecode(req_->getFile()); + request += + util::percentDecode(req_->getFile().begin(), req_->getFile().end()); request += "\r\n"; A2_LOG_INFO(fmt(MSG_SENDING_REQUEST, cuid_, request.c_str())); @@ -173,7 +174,8 @@ bool FtpConnection::sendSize() { if(socketBuffer_.sendBufferIsEmpty()) { std::string request = "SIZE "; - request += util::percentDecode(req_->getFile()); + request += + util::percentDecode(req_->getFile().begin(), req_->getFile().end()); request += "\r\n"; A2_LOG_INFO(fmt(MSG_SENDING_REQUEST, cuid_, request.c_str())); @@ -293,7 +295,8 @@ bool FtpConnection::sendRetr() { if(socketBuffer_.sendBufferIsEmpty()) { std::string request = "RETR "; - request += util::percentDecode(req_->getFile()); + request += + util::percentDecode(req_->getFile().begin(), req_->getFile().end()); request += "\r\n"; A2_LOG_INFO(fmt(MSG_SENDING_REQUEST, cuid_, request.c_str())); diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc index c249feab..3a527477 100644 --- a/src/FtpNegotiationCommand.cc +++ b/src/FtpNegotiationCommand.cc @@ -369,7 +369,8 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength) getFileEntry()->setPath (util::createSafePath (getOption()->get(PREF_DIR), - util::percentDecode(getRequest()->getFile()))); + util::percentDecode(getRequest()->getFile().begin(), + getRequest()->getFile().end()))); } getRequestGroup()->preDownloadProcessing(); if(getDownloadEngine()->getRequestGroupMan()-> diff --git a/src/HttpRequestCommand.cc b/src/HttpRequestCommand.cc index b9146760..74ba8e10 100644 --- a/src/HttpRequestCommand.cc +++ b/src/HttpRequestCommand.cc @@ -161,7 +161,8 @@ bool HttpRequestCommand::executeInternal() { getFileEntry()->setPath (util::createSafePath (getOption()->get(PREF_DIR), - util::percentDecode(getRequest()->getFile()))); + util::percentDecode(getRequest()->getFile().begin(), + getRequest()->getFile().end()))); } File ctrlfile(getFileEntry()->getPath()+ DefaultBtProgressInfoFile::getSuffix()); diff --git a/src/HttpResponse.cc b/src/HttpResponse.cc index 225dd156..993f2604 100644 --- a/src/HttpResponse.cc +++ b/src/HttpResponse.cc @@ -120,7 +120,9 @@ std::string HttpResponse::determinFilename() const util::getContentDispositionFilename (httpHeader_->getFirst(HttpHeader::CONTENT_DISPOSITION)); if(contentDisposition.empty()) { - std::string file = util::percentDecode(httpRequest_->getFile()); + std::string file = + util::percentDecode(httpRequest_->getFile().begin(), + httpRequest_->getFile().end()); if(file.empty()) { return "index.html"; } else { diff --git a/src/json.cc b/src/json.cc index 501c9cff..ae464848 100644 --- a/src/json.cc +++ b/src/json.cc @@ -617,38 +617,46 @@ decodeGetParams(const std::string& query) std::string jsonRequest; std::string callback; if(!query.empty() && query[0] == '?') { - std::string method; - std::string id; - std::string params; + Scip method; + Scip id; + Scip params; std::vector getParams; util::split(query.substr(1), std::back_inserter(getParams), "&"); for(std::vector::const_iterator i = getParams.begin(), eoi = getParams.end(); i != eoi; ++i) { if(util::startsWith(*i, "method=")) { - method = (*i).substr(7); + method.first = (*i).begin()+7; + method.second = (*i).end(); } else if(util::startsWith(*i, "id=")) { - id = (*i).substr(3); + id.first = (*i).begin()+3; + id.second = (*i).end(); } else if(util::startsWith(*i, "params=")) { - params = (*i).substr(7); + params.first = (*i).begin()+7; + params.second = (*i).end(); } else if(util::startsWith(*i, "jsoncallback=")) { - callback = (*i).substr(13); + callback.assign((*i).begin()+13, (*i).end()); } } std::string jsonParam = - Base64::decode(util::percentDecode(params)); - if(method.empty() && id.empty()) { + Base64::decode(util::percentDecode(params.first, params.second)); + if(method.first == method.second && id.first == id.second) { // Assume batch call. jsonRequest = jsonParam; } else { jsonRequest = '{'; - if(!method.empty()) { - strappend(jsonRequest, "\"method\":\"", method, "\""); + if(method.first != method.second) { + jsonRequest += "\"method\":\""; + jsonRequest.append(method.first, method.second); + jsonRequest += '"'; } - if(!id.empty()) { - strappend(jsonRequest, ",\"id\":\"", id, "\""); + if(id.first != id.second) { + jsonRequest += ",\"id\":\""; + jsonRequest.append(id.first, id.second); + jsonRequest += '"'; } - if(!params.empty()) { - strappend(jsonRequest, ",\"params\":", jsonParam); + if(params.first != params.second) { + jsonRequest += ",\"params\":"; + jsonRequest += jsonParam; } jsonRequest += '}'; } diff --git a/src/magnet.cc b/src/magnet.cc index 5738b194..bf7ceabe 100644 --- a/src/magnet.cc +++ b/src/magnet.cc @@ -51,16 +51,17 @@ SharedHandle parse(const std::string& magnet) std::back_inserter(queries), "&"); for(std::vector::const_iterator i = queries.begin(), eoi = queries.end(); i != eoi; ++i) { - std::pair kv; - util::divide(kv, *i, '='); - std::string value = util::percentDecode(kv.second); - List* l = downcast(dict->get(kv.first)); + std::string::const_iterator eq = std::find((*i).begin(), (*i).end(), '='); + std::string name((*i).begin(), eq); + std::string value = + eq == (*i).end() ? "" : util::percentDecode(eq+1, (*i).end()); + List* l = downcast(dict->get(name)); if(l) { l->append(String::g(value)); } else { SharedHandle l = List::g(); l->append(String::g(value)); - dict->put(kv.first, l); + dict->put(name, l); } } return dict; diff --git a/src/uri.cc b/src/uri.cc index b1df0e52..28ebe27b 100644 --- a/src/uri.cc +++ b/src/uri.cc @@ -159,13 +159,13 @@ bool parse(UriStruct& result, const std::string& uri) for(; userLast != userInfoLast; ++userLast) { if(*userLast == ':') { result.password = - util::percentDecode(std::string(userLast+1,userInfoLast)); + util::percentDecode(userLast+1,userInfoLast); result.hasPassword = true; break; } } result.username = - util::percentDecode(std::string(authorityFirst, userLast)); + util::percentDecode(authorityFirst, userLast); break; } } diff --git a/src/util.cc b/src/util.cc index 2d65f509..5a115d50 100644 --- a/src/util.cc +++ b/src/util.cc @@ -484,20 +484,21 @@ std::string torrentPercentEncode(const std::string& target) (reinterpret_cast(target.c_str()), target.size()); } -std::string percentDecode(const std::string& target) { +std::string percentDecode +(std::string::const_iterator first, std::string::const_iterator last) +{ std::string result; - for(std::string::const_iterator itr = target.begin(), eoi = target.end(); - itr != eoi; ++itr) { - if(*itr == '%') { - if(itr+1 != target.end() && itr+2 != target.end() && - isHexDigit(*(itr+1)) && isHexDigit(*(itr+2))) { - result += parseInt(itr+1, itr+3, 16); - itr += 2; + for(; first != last; ++first) { + if(*first == '%') { + if(first+1 != last && first+2 != last && + isHexDigit(*(first+1)) && isHexDigit(*(first+2))) { + result += parseInt(first+1, first+3, 16); + first += 2; } else { - result += *itr; + result += *first; } } else { - result += *itr; + result += *first; } } return result; @@ -863,7 +864,7 @@ std::string getContentDispositionFilename(const std::string& header) if(bad) { continue; } - value = percentDecode(value); + value = percentDecode(value.begin(), value.end()); if(toLower(extValues[0]) == "iso-8859-1") { value = iso8859ToUtf8(value); } @@ -895,7 +896,7 @@ std::string getContentDispositionFilename(const std::string& header) filenameLast = value.end(); } static const std::string TRIMMED("\r\n\t '\""); - value = percentDecode(std::string(value.begin(), filenameLast)); + value = percentDecode(value.begin(), filenameLast); value = strip(value, TRIMMED); value.erase(std::remove(value.begin(), value.end(), '\\'), value.end()); if(!detectDirTraversal(value) && diff --git a/src/util.h b/src/util.h index c6ffb2d4..2fe18743 100644 --- a/src/util.h +++ b/src/util.h @@ -184,7 +184,8 @@ bool inRFC3986UnreservedChars(const char c); bool isUtf8(const std::string& str); -std::string percentDecode(const std::string& target); +std::string percentDecode +(std::string::const_iterator first, std::string::const_iterator last); std::string torrentPercentEncode(const unsigned char* target, size_t len); diff --git a/test/UtilTest.cc b/test/UtilTest.cc index 6d089ac3..51def745 100644 --- a/test/UtilTest.cc +++ b/test/UtilTest.cc @@ -569,22 +569,27 @@ void UtilTest::testLowercase() { void UtilTest::testPercentDecode() { std::string src = "http://aria2.sourceforge.net/aria2%200.7.0%20docs.html"; CPPUNIT_ASSERT_EQUAL(std::string("http://aria2.sourceforge.net/aria2 0.7.0 docs.html"), - util::percentDecode(src)); + util::percentDecode(src.begin(), src.end())); std::string src2 = "aria2+aria2"; - CPPUNIT_ASSERT_EQUAL(std::string("aria2+aria2"), util::percentDecode(src2)); + CPPUNIT_ASSERT_EQUAL(std::string("aria2+aria2"), + util::percentDecode(src2.begin(), src2.end())); std::string src3 = "%5t%20"; - CPPUNIT_ASSERT_EQUAL(std::string("%5t "), util::percentDecode(src3)); + CPPUNIT_ASSERT_EQUAL(std::string("%5t "), + util::percentDecode(src3.begin(), src3.end())); std::string src4 = "%"; - CPPUNIT_ASSERT_EQUAL(std::string("%"), util::percentDecode(src4)); + CPPUNIT_ASSERT_EQUAL(std::string("%"), + util::percentDecode(src4.begin(), src4.end())); std::string src5 = "%3"; - CPPUNIT_ASSERT_EQUAL(std::string("%3"), util::percentDecode(src5)); + CPPUNIT_ASSERT_EQUAL(std::string("%3"), + util::percentDecode(src5.begin(), src5.end())); std::string src6 = "%2f"; - CPPUNIT_ASSERT_EQUAL(std::string("/"), util::percentDecode(src6)); + CPPUNIT_ASSERT_EQUAL(std::string("/"), + util::percentDecode(src6.begin(), src6.end())); } void UtilTest::testGetRealSize()