From 10e371c25a9185d3d2d02ddd3d40dfcbc49967d5 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 17 Oct 2009 13:11:03 +0000 Subject: [PATCH] 2009-10-17 Tatsuhiro Tsujikawa Fixed the bug that Netrc::parse() cannot recognize comment line. * src/Netrc.cc * src/Util.h * test/NetrcTest.cc * test/sample.netrc --- ChangeLog | 8 ++++ src/Netrc.cc | 99 ++++++++++++++++++++++++++++++----------------- src/Util.h | 31 +++++++++++++++ test/NetrcTest.cc | 4 +- test/sample.netrc | 3 ++ 5 files changed, 108 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4a3b6f98..eb74e885 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-10-17 Tatsuhiro Tsujikawa + + Fixed the bug that Netrc::parse() cannot recognize comment line. + * src/Netrc.cc + * src/Util.h + * test/NetrcTest.cc + * test/sample.netrc + 2009-10-13 Tatsuhiro Tsujikawa Fixed typo diff --git a/src/Netrc.cc b/src/Netrc.cc index 96011398..453cddbd 100644 --- a/src/Netrc.cc +++ b/src/Netrc.cc @@ -36,10 +36,12 @@ #include #include +#include #include "DlAbortEx.h" #include "StringFormat.h" #include "A2STR.h" +#include "Util.h" namespace aria2 { @@ -55,21 +57,9 @@ const std::string Netrc::ACCOUNT("account"); const std::string Netrc::MACDEF("macdef"); -std::string Netrc::getRequiredNextToken(std::ifstream& f) const -{ - std::string token; - if(f >> token) { - return token; - } else { - throw DL_ABORT_EX - ("Netrc:parse error. EOF reached where a token expected."); - } -} - void Netrc::skipMacdef(std::ifstream& f) const { std::string line; - getline(f, line); while(getline(f, line)) { if(line == A2STR::CR_C || line.empty()) { break; @@ -87,32 +77,69 @@ void Netrc::parse(const std::string& path) (StringFormat("File not found: %s", path.c_str()).str()); } + enum STATE { + GET_TOKEN, + SET_MACHINE, + SET_LOGIN, + SET_PASSWORD, + SET_ACCOUNT, + SET_MACDEF + }; AuthenticatorHandle authenticator; - std::string token; - while(f >> token) { - if(token == Netrc::MACHINE) { - storeAuthenticator(authenticator); - authenticator.reset(new Authenticator()); - authenticator->setMachine(getRequiredNextToken(f)); - } else if(token == Netrc::DEFAULT) { - storeAuthenticator(authenticator); - authenticator.reset(new DefaultAuthenticator()); - } else { - if(authenticator.isNull()) { - throw DL_ABORT_EX - ("Netrc:parse error. %s encounterd where 'machine' or 'default' expected."); - } - if(token == Netrc::LOGIN) { - authenticator->setLogin(getRequiredNextToken(f)); - } else if(token == Netrc::PASSWORD) { - authenticator->setPassword(getRequiredNextToken(f)); - } else if(token == Netrc::ACCOUNT) { - authenticator->setAccount(getRequiredNextToken(f)); - } else if(token == Netrc::MACDEF) { - getRequiredNextToken(f); - skipMacdef(f); - } + std::string line; + STATE state = GET_TOKEN; + while(getline(f, line)) { + if(Util::startsWith(line, "#")) { + continue; } + std::vector tokens; + Util::split(line, std::back_inserter(tokens), " \t", true); + for(std::vector::const_iterator iter = tokens.begin(); + iter != tokens.end(); ++iter) { + const std::string& token = *iter; + if(state == GET_TOKEN) { + if(token == Netrc::MACHINE) { + storeAuthenticator(authenticator); + authenticator.reset(new Authenticator()); + state = SET_MACHINE; + } else if(token == Netrc::DEFAULT) { + storeAuthenticator(authenticator); + authenticator.reset(new DefaultAuthenticator()); + } else { + if(authenticator.isNull()) { + throw DL_ABORT_EX + (StringFormat("Netrc:parse error. %s encounterd where 'machine'" + " or 'default' expected.", token.c_str()).str()); + } + if(token == Netrc::LOGIN) { + state = SET_LOGIN; + } else if(token == Netrc::PASSWORD) { + state = SET_PASSWORD; + } else if(token == Netrc::ACCOUNT) { + state = SET_ACCOUNT; + } else if(token == Netrc::MACDEF) { + state = SET_MACDEF; + } + } + } else { + if(state == SET_MACHINE) { + authenticator->setMachine(token); + } else if(state == SET_LOGIN) { + authenticator->setLogin(token); + } else if(state == SET_PASSWORD) { + authenticator->setPassword(token); + } else if(state == SET_ACCOUNT) { + authenticator->setAccount(token); + } else if(state == SET_MACDEF) { + skipMacdef(f); + } + state = GET_TOKEN; + } + } + } + if(state != GET_TOKEN) { + throw DL_ABORT_EX + ("Netrc:parse error. EOF reached where a token expected."); } storeAuthenticator(authenticator); } diff --git a/src/Util.h b/src/Util.h index ff0e1827..4508f14c 100644 --- a/src/Util.h +++ b/src/Util.h @@ -140,6 +140,37 @@ public: static void slice(std::deque& result, const std::string& src, char delim, bool trim = false); + template + static OutputIterator split(const std::string& src, OutputIterator out, + const std::string& delims, bool doTrim = false) + { + std::string::size_type p = 0; + while(1) { + std::string::size_type np = src.find_first_of(delims, p); + if(np == std::string::npos) { + std::string term = src.substr(p); + if(doTrim) { + term = trim(term); + } + if(!term.empty()) { + *out = term; + ++out; + } + break; + } + std::string term = src.substr(p, np-p); + if(doTrim) { + term = trim(term); + } + p = np+1; + if(!term.empty()) { + *out = term; + ++out; + } + } + return out; + } + static const std::string DEFAULT_TRIM_CHARSET; static std::string trim(const std::string& src, diff --git a/test/NetrcTest.cc b/test/NetrcTest.cc index 3af084f4..5c2d267c 100644 --- a/test/NetrcTest.cc +++ b/test/NetrcTest.cc @@ -1,8 +1,10 @@ #include "Netrc.h" -#include "Exception.h" + #include #include +#include "Exception.h" + namespace aria2 { class NetrcTest : public CppUnit::TestFixture { diff --git a/test/sample.netrc b/test/sample.netrc index 4df1a244..bdd1737b 100644 --- a/test/sample.netrc +++ b/test/sample.netrc @@ -1,3 +1,4 @@ +#sample netrc file for unit testing machine host1 login tujikawa password tujikawapassword @@ -9,5 +10,7 @@ machine host2 login aria2 password aria2password account aria2account +macdef init +#another comment line default login anonymous password ARIA2@USER account ARIA2@ACCT \ No newline at end of file