From 6ef91d60b34a2a93b397b6db4daabfe8017d31fb Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 3 Nov 2011 16:19:21 +0900 Subject: [PATCH] Rewritten util::stripIter(), which now returns pair of iterator. --- src/HttpHeader.cc | 24 ++------------ src/HttpResponse.cc | 7 +++-- src/NsCookieParser.cc | 3 +- src/ServerStatMan.cc | 7 +++-- src/Sqlite3CookieParser.cc | 2 +- src/cookie_helper.cc | 64 +++++++++++++++++++++++--------------- src/cookie_helper.h | 9 ++++-- src/util.cc | 12 +++++-- src/util.h | 36 +++++++++++---------- test/CookieHelperTest.cc | 28 +++++++++++------ 10 files changed, 108 insertions(+), 84 deletions(-) diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc index a3e53def..d33735e3 100644 --- a/src/HttpHeader.cc +++ b/src/HttpHeader.cc @@ -198,24 +198,6 @@ void HttpHeader::setRequestPath(const std::string& requestPath) requestPath_ = requestPath; } -namespace { -template -std::pair stripIter2 -(InputIterator first, InputIterator last, - const std::string& chars = "\r\n \t") -{ - for(; first != last && - std::find(chars.begin(), chars.end(), *first) != chars.end(); ++first); - if(first == last) { - return std::make_pair(first, last); - } - InputIterator left = last-1; - for(; left != first && - std::find(chars.begin(), chars.end(), *left) != chars.end(); --left); - return std::make_pair(first, left+1); -} -} // namespace - void HttpHeader::fill (std::string::const_iterator first, std::string::const_iterator last) @@ -233,7 +215,7 @@ void HttpHeader::fill // multiline header? if(*first == ' ' || *first == '\t') { std::pair p = stripIter2(first, j); + std::string::const_iterator> p = util::stripIter(first, j); if(!name.empty() && p.first != p.second) { if(!value.empty()) { value += ' '; @@ -246,9 +228,9 @@ void HttpHeader::fill put(name, value); } std::pair p = stripIter2(first, sep); + std::string::const_iterator> p = util::stripIter(first, sep); name.assign(p.first, p.second); - p = stripIter2(sep+1, j); + p = util::stripIter(sep+1, j); value.assign(p.first, p.second); } } diff --git a/src/HttpResponse.cc b/src/HttpResponse.cc index 0c879291..d346a755 100644 --- a/src/HttpResponse.cc +++ b/src/HttpResponse.cc @@ -309,11 +309,12 @@ bool parseMetalinkHttpLink(MetalinkHttpEntry& result, const std::string& s) if(last == s.end()) { return false; } - std::string uri = util::stripIter(first+1, last); - if(uri.empty()) { + std::pair p = util::stripIter(first+1, last); + if(p.first == p.second) { return false; } else { - result.uri = uri; + result.uri.assign(p.first, p.second); } last = std::find(last, s.end(), ';'); if(last != s.end()) { diff --git a/src/NsCookieParser.cc b/src/NsCookieParser.cc index 47465b80..eee17ea1 100644 --- a/src/NsCookieParser.cc +++ b/src/NsCookieParser.cc @@ -66,7 +66,8 @@ bool parseNsCookie return false; } std::string cookieDomain = cookie::removePrecedingDots(vs[0]); - if(vs[5].empty() || cookieDomain.empty() || !cookie::goodPath(vs[2])) { + if(vs[5].empty() || cookieDomain.empty() || + !cookie::goodPath(vs[2].begin(), vs[2].end())) { return false; } int64_t expiryTime; diff --git a/src/ServerStatMan.cc b/src/ServerStatMan.cc index 37695d18..3804c901 100644 --- a/src/ServerStatMan.cc +++ b/src/ServerStatMan.cc @@ -148,10 +148,13 @@ bool ServerStatMan::load(const std::string& filename) return false; } } - std::string line = util::stripIter(&buf[0], &buf[strlen(buf)]); - if(line.empty()) { + std::pair p = + util::stripIter(&buf[0], &buf[strlen(buf)]); + if(p.first == p.second) { continue; } + std::string line(p.first, p.second); std::vector items; util::split(line, std::back_inserter(items), ","); std::map m; diff --git a/src/Sqlite3CookieParser.cc b/src/Sqlite3CookieParser.cc index 804e691d..1de7b225 100644 --- a/src/Sqlite3CookieParser.cc +++ b/src/Sqlite3CookieParser.cc @@ -108,7 +108,7 @@ int cookieRowMapper(void* data, int columns, char** values, char** names) std::string cookieName = toString(values[4]); std::string cookiePath = toString(values[1]); if(cookieName.empty() || cookieDomain.empty() || - !cookie::goodPath(cookiePath)) { + !cookie::goodPath(cookiePath.begin(), cookiePath.end())) { return 0; } int64_t expiryTime; diff --git a/src/cookie_helper.cc b/src/cookie_helper.cc index c3cef6da..f98175c9 100644 --- a/src/cookie_helper.cc +++ b/src/cookie_helper.cc @@ -65,13 +65,16 @@ std::string::const_iterator getNextDigit } } // namespace -bool parseDate(time_t& time, const std::string& cookieDate) +bool parseDate +(time_t& time, + std::string::const_iterator first, + std::string::const_iterator last) { // Following algorithm is described in // http://tools.ietf.org/html/rfc6265#section-5.1.1 std::vector dateTokens; - for(std::string::const_iterator i = cookieDate.begin(), - eoi = cookieDate.end(); i != eoi;) { + for(std::string::const_iterator i = first, + eoi = last; i != eoi;) { unsigned char c = *i; if(isDelimiter(c)) { ++i; @@ -210,12 +213,16 @@ bool parse if(eq == nvEnd) { return false; } - std::string cookieName = util::stripIter(cookieStr.begin(), eq); - if(cookieName.empty()) { + std::pair p = + util::stripIter(cookieStr.begin(), eq); + if(p.first == p.second) { return false; } - std::string cookieValue = util::stripIter(eq+1, nvEnd); - cookieValue = util::strip(cookieValue, "\""); + std::string cookieName(p.first, p.second); + p = util::stripIter(eq+1, nvEnd); + p = util::stripIter(p.first, p.second, "\""); + std::string cookieValue(p.first, p.second); time_t expiryTime = 0; bool foundExpires = false; bool persistent = false; @@ -233,36 +240,41 @@ bool parse for(std::string::const_iterator i = nvEnd; i != end;) { std::string::const_iterator j = std::find(i, end, ';'); std::string::const_iterator eq = std::find(i, j, '='); - std::string attrName = util::stripIter(i, eq); + p = util::stripIter(i, eq); + std::string attrName(p.first, p.second); util::lowercase(attrName); - std::string attrValue; - if(eq != j) { - attrValue = util::stripIter(eq+1, j); + std::pair attrp; + if(eq == j) { + attrp.first = attrp.second = j; + } else { + attrp = util::stripIter(eq+1, j); } i = j; if(j != end) { ++i; } if(attrName == "expires") { - if(parseDate(expiryTime, attrValue)) { + if(parseDate(expiryTime, attrp.first, attrp.second)) { foundExpires = true; } else { return false; } } else if(attrName == "max-age") { - if(attrValue.empty() || - (!in(static_cast(attrValue[0]), 0x30u, 0x39u) && - attrValue[0] != '-')) { + if(attrp.first == attrp.second || + (!in(static_cast(*attrp.first), 0x30u, 0x39u) && + *attrp.first != '-')) { return false; } - for(std::string::const_iterator s = attrValue.begin()+1, - eos = attrValue.end(); s != eos; ++s) { + for(std::string::const_iterator s = attrp.first+1, + eos = attrp.second; s != eos; ++s) { if(!in(static_cast(*s), 0x30u, 0x39u)) { return false; } } int64_t delta; - if(util::parseLLIntNoThrow(delta, attrValue)) { + if(util::parseLLIntNoThrow(delta, + std::string(attrp.first, attrp.second))) { foundMaxAge = true; if(delta <= 0) { maxAge = 0; @@ -279,19 +291,19 @@ bool parse return false; } } else if(attrName == "domain") { - if(attrValue.empty()) { + if(attrp.first == attrp.second) { return false; } - std::string::const_iterator noDot = attrValue.begin(); - std::string::const_iterator end = attrValue.end(); + std::string::const_iterator noDot = attrp.first; + std::string::const_iterator end = attrp.second; for(; noDot != end && *noDot == '.'; ++noDot); if(noDot == end) { return false; } cookieDomain = std::string(noDot, end); } else if(attrName == "path") { - if(goodPath(attrValue)) { - cookiePath = attrValue; + if(goodPath(attrp.first, attrp.second)) { + cookiePath.assign(attrp.first, attrp.second); } else { cookiePath = defaultPath; } @@ -349,9 +361,11 @@ std::string removePrecedingDots(const std::string& host) return std::string(noDot, end); } -bool goodPath(const std::string& cookiePath) +bool goodPath +(std::string::const_iterator first, + std::string::const_iterator last) { - return !cookiePath.empty() && cookiePath[0] == '/'; + return first != last && *first == '/'; } std::string canonicalizeHost(const std::string& host) diff --git a/src/cookie_helper.h b/src/cookie_helper.h index 6dc249eb..50e15eba 100644 --- a/src/cookie_helper.h +++ b/src/cookie_helper.h @@ -47,7 +47,10 @@ class Cookie; namespace cookie { -bool parseDate(time_t& time, const std::string& cookieDate); +bool parseDate +(time_t& time, + std::string::const_iterator first, + std::string::const_iterator last); bool parse (Cookie& cookie, @@ -58,7 +61,9 @@ bool parse std::string removePrecedingDots(const std::string& host); -bool goodPath(const std::string& cookiePath); +bool goodPath +(std::string::const_iterator first, + std::string::const_iterator last); std::string canonicalizeHost(const std::string& host); diff --git a/src/util.cc b/src/util.cc index 04a65e4b..ce60d610 100644 --- a/src/util.cc +++ b/src/util.cc @@ -190,7 +190,10 @@ const std::string DEFAULT_STRIP_CHARSET("\r\n\t "); std::string strip(const std::string& str, const std::string& chars) { - return stripIter(str.begin(), str.end(), chars); + std::pair p = + stripIter(str.begin(), str.end(), chars); + return std::string(p.first, p.second); } void divide @@ -203,8 +206,11 @@ void divide hp.first = strip(src); hp.second = A2STR::NIL; } else { - hp.first = stripIter(first, dpos); - hp.second = stripIter(dpos+1, last); + std::pair p = stripIter(first, dpos); + hp.first.assign(p.first, p.second); + p = stripIter(dpos+1, last); + hp.second.assign(p.first, p.second); } } diff --git a/src/util.h b/src/util.h index 147126d4..7cccfdab 100644 --- a/src/util.h +++ b/src/util.h @@ -142,22 +142,19 @@ int32_t difftvsec(struct timeval tv1, struct timeval tv2); extern const std::string DEFAULT_STRIP_CHARSET; template -std::string stripIter +std::pair stripIter (InputIterator first, InputIterator last, const std::string& chars = DEFAULT_STRIP_CHARSET) { - if(std::distance(first, last) == 0) { - return A2STR::NIL; - } for(; first != last && std::find(chars.begin(), chars.end(), *first) != chars.end(); ++first); if(first == last) { - return A2STR::NIL; + return std::make_pair(first, last); } InputIterator left = last-1; for(; left != first && std::find(chars.begin(), chars.end(), *left) != chars.end(); --left); - return std::string(first, left+1); + return std::make_pair(first, left+1); } std::string strip @@ -367,9 +364,13 @@ OutputIterator split(const std::string& src, OutputIterator out, std::string::const_iterator j = i; for(; j != last && std::find(delims.begin(), delims.end(), *j) == delims.end(); ++j); - std::string t = doStrip?util::stripIter(i, j):std::string(i, j); - if(allowEmpty || !t.empty()) { - *out++ = t; + std::pair p(i, j); + if(doStrip) { + p = stripIter(i, j); + } + if(allowEmpty || p.first != p.second) { + *out++ = std::string(p.first, p.second); } i = j; if(j != last) { @@ -489,24 +490,27 @@ nextParam parmnameLast = last; } } - std::string tname, tvalue; + std::pair namep; + std::pair valuep; if(parmnameFirst == parmnameLast) { if(!eqFound) { parmnameFirst = first; parmnameLast = last; - tname = util::stripIter(parmnameFirst, parmnameLast); + namep = stripIter(parmnameFirst, parmnameLast); } } else { first = parmnameLast+1; - tname = util::stripIter(parmnameFirst, parmnameLast); - tvalue = util::stripIter(first, last); + namep = stripIter(parmnameFirst, parmnameLast); + valuep = stripIter(first, last); } if(last != end) { ++last; } - if(!tname.empty()) { - name.swap(tname); - value.swap(tvalue); + if(namep.first != namep.second) { + name.assign(namep.first, namep.second); + value.assign(valuep.first, valuep.second); return std::make_pair(last, true); } first = last; diff --git a/test/CookieHelperTest.cc b/test/CookieHelperTest.cc index dd39f502..e1b3c5f4 100644 --- a/test/CookieHelperTest.cc +++ b/test/CookieHelperTest.cc @@ -34,25 +34,33 @@ void CookieHelperTest::testParseDate() { // RFC1123 time_t time = 0; - CPPUNIT_ASSERT(cookie::parseDate(time, "Sat, 06 Sep 2008 15:26:33 GMT")); + std::string s = "Sat, 06 Sep 2008 15:26:33 GMT"; + CPPUNIT_ASSERT(cookie::parseDate(time, s.begin(), s.end())); CPPUNIT_ASSERT_EQUAL((time_t)1220714793, time); // RFC850 - CPPUNIT_ASSERT(cookie::parseDate(time, "Saturday, 06-Sep-08 15:26:33 GMT")); + s = "Saturday, 06-Sep-08 15:26:33 GMT"; + CPPUNIT_ASSERT(cookie::parseDate(time, s.begin(), s.end())); CPPUNIT_ASSERT_EQUAL((time_t)1220714793, time); // ANSI C's asctime() - CPPUNIT_ASSERT(cookie::parseDate(time, "Sun Sep 6 15:26:33 2008")); + s = "Sun Sep 6 15:26:33 2008"; + CPPUNIT_ASSERT(cookie::parseDate(time, s.begin(), s.end())); CPPUNIT_ASSERT_EQUAL((time_t)1220714793, time); - - CPPUNIT_ASSERT(cookie::parseDate(time, "Thu Jan 1 0:0:0 1970")); + s = "Thu Jan 1 0:0:0 1970"; + CPPUNIT_ASSERT(cookie::parseDate(time, s.begin(), s.end())); CPPUNIT_ASSERT_EQUAL((time_t)0, time); - CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu Jan 1 1970 0:")); - CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu Jan 1 1970 0:0")); - CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu Jan 1 1970 0:0:")); + s = "Thu Jan 1 1970 0:"; + CPPUNIT_ASSERT(!cookie::parseDate(time, s.begin(), s.end())); + s = "Thu Jan 1 1970 0:0"; + CPPUNIT_ASSERT(!cookie::parseDate(time, s.begin(), s.end())); + s = "Thu Jan 1 1970 0:0:"; + CPPUNIT_ASSERT(!cookie::parseDate(time, s.begin(), s.end())); // Leap year - CPPUNIT_ASSERT(cookie::parseDate(time, "Tue, 29 Feb 2000 00:00:00 GMT")); - CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu, 29 Feb 2001 00:00:00 GMT")); + s = "Tue, 29 Feb 2000 00:00:00 GMT"; + CPPUNIT_ASSERT(cookie::parseDate(time, s.begin(), s.end())); + s = "Thu, 29 Feb 2001 00:00:00 GMT"; + CPPUNIT_ASSERT(!cookie::parseDate(time, s.begin(), s.end())); } void CookieHelperTest::testDomainMatch()