Allow subsecond value in ns cookie.txt file's expiry time field

dynamic-select-file
Tatsuhiro Tsujikawa 2016-05-15 18:40:50 +09:00
parent 6976ffed9e
commit bafbbe7c1d
7 changed files with 64 additions and 9 deletions

View File

@ -69,10 +69,15 @@ std::unique_ptr<Cookie> parseNsCookie(const std::string& cookieStr,
return nullptr; return nullptr;
} }
int64_t expiryTime; int64_t expiryTime;
if (!util::parseLLIntNoThrow(expiryTime, {
// chrome extension uses subsecond resolution for expiry time.
double expiryTimeDouble;
if (!util::parseDoubleNoThrow(expiryTimeDouble,
std::string(vs[4].first, vs[4].second))) { std::string(vs[4].first, vs[4].second))) {
return nullptr; return nullptr;
} }
expiryTime = static_cast<int64_t>(expiryTimeDouble);
}
if (std::numeric_limits<time_t>::max() < expiryTime) { if (std::numeric_limits<time_t>::max() < expiryTime) {
expiryTime = std::numeric_limits<time_t>::max(); expiryTime = std::numeric_limits<time_t>::max();
} }

View File

@ -596,6 +596,33 @@ bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base)
} }
} }
bool parseDoubleNoThrow(double& res, const std::string& s)
{
if (s.empty()) {
return false;
}
errno = 0;
char* endptr;
auto d = strtod(s.c_str(), &endptr);
if (errno == ERANGE) {
return false;
}
if (endptr != s.c_str() + s.size()) {
for (auto i = std::begin(s) + (endptr - s.c_str()); i != std::end(s); ++i) {
if (!isspace(*i)) {
return false;
}
}
}
res = d;
return true;
}
SegList<int> parseIntSegments(const std::string& src) SegList<int> parseIntSegments(const std::string& src)
{ {
SegList<int> sgl; SegList<int> sgl;

View File

@ -280,6 +280,10 @@ bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base = 10);
bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base = 10); bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base = 10);
// Parses |s| as floating point number, and stores the result into
// |res|. This function returns true if it succeeds.
bool parseDoubleNoThrow(double& res, const std::string& s);
SegList<int> parseIntSegments(const std::string& src); SegList<int> parseIntSegments(const std::string& src);
// Parses string which specifies the range of piece index for higher // Parses string which specifies the range of piece index for higher

View File

@ -328,10 +328,10 @@ void CookieStorageTest::testLoad()
c = cookies[3]; c = cookies[3];
CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName()); CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName());
CPPUNIT_ASSERT_EQUAL(std::string("1000"), c->getValue()); CPPUNIT_ASSERT_EQUAL(std::string("1000"), c->getValue());
CPPUNIT_ASSERT((time_t)INT32_MAX <= c->getExpiryTime()); CPPUNIT_ASSERT_EQUAL((time_t)1463304912, c->getExpiryTime());
CPPUNIT_ASSERT(c->getPersistent()); CPPUNIT_ASSERT(c->getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath()); CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c->getDomain()); CPPUNIT_ASSERT_EQUAL(std::string("something"), c->getDomain());
CPPUNIT_ASSERT(!c->getSecure()); CPPUNIT_ASSERT(!c->getSecure());
} }

View File

@ -69,9 +69,9 @@ void NsCookieParserTest::testParse()
c = cookies[3].get(); c = cookies[3].get();
CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName()); CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName());
CPPUNIT_ASSERT_EQUAL(std::string("1000"), c->getValue()); CPPUNIT_ASSERT_EQUAL(std::string("1000"), c->getValue());
CPPUNIT_ASSERT((time_t)INT32_MAX <= c->getExpiryTime()); CPPUNIT_ASSERT_EQUAL((time_t)1463304912, c->getExpiryTime());
CPPUNIT_ASSERT(c->getPersistent()); CPPUNIT_ASSERT(c->getPersistent());
CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c->getDomain()); CPPUNIT_ASSERT_EQUAL(std::string("something"), c->getDomain());
CPPUNIT_ASSERT(c->getHostOnly()); CPPUNIT_ASSERT(c->getHostOnly());
CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath()); CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
CPPUNIT_ASSERT(!c->getSecure()); CPPUNIT_ASSERT(!c->getSecure());

View File

@ -66,6 +66,7 @@ class UtilTest2 : public CppUnit::TestFixture {
CPPUNIT_TEST(testInPrivateAddress); CPPUNIT_TEST(testInPrivateAddress);
CPPUNIT_TEST(testSecfmt); CPPUNIT_TEST(testSecfmt);
CPPUNIT_TEST(testTlsHostnameMatch); CPPUNIT_TEST(testTlsHostnameMatch);
CPPUNIT_TEST(testParseDoubleNoThrow);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
@ -115,6 +116,7 @@ public:
void testInPrivateAddress(); void testInPrivateAddress();
void testSecfmt(); void testSecfmt();
void testTlsHostnameMatch(); void testTlsHostnameMatch();
void testParseDoubleNoThrow();
}; };
CPPUNIT_TEST_SUITE_REGISTRATION(UtilTest2); CPPUNIT_TEST_SUITE_REGISTRATION(UtilTest2);
@ -978,4 +980,21 @@ void UtilTest2::testTlsHostnameMatch()
CPPUNIT_ASSERT(!util::tlsHostnameMatch("xn--*.a.b", "xn--c.a.b")); CPPUNIT_ASSERT(!util::tlsHostnameMatch("xn--*.a.b", "xn--c.a.b"));
} }
void UtilTest2::testParseDoubleNoThrow()
{
double n;
CPPUNIT_ASSERT(util::parseDoubleNoThrow(n, " 123 "));
CPPUNIT_ASSERT_EQUAL(123., n);
CPPUNIT_ASSERT(util::parseDoubleNoThrow(n, "3.14"));
CPPUNIT_ASSERT_EQUAL(3.14, n);
CPPUNIT_ASSERT(util::parseDoubleNoThrow(n, "-3.14"));
CPPUNIT_ASSERT_EQUAL(-3.14, n);
CPPUNIT_ASSERT(!util::parseDoubleNoThrow(n, ""));
CPPUNIT_ASSERT(!util::parseDoubleNoThrow(n, "123x"));
}
} // namespace aria2 } // namespace aria2

View File

@ -5,5 +5,5 @@ expired FALSE / FALSE 1000 user me
192.168.0.1 TRUE /cgi-bin FALSE 0 passwd secret 192.168.0.1 TRUE /cgi-bin FALSE 0 passwd secret
badformat badformat
overflow FALSE / FALSE 9223372036854775807 TAX 1000 something FALSE / FALSE 1463304912.5 TAX 1000
.example.org TRUE / FALSE 2147483647 novalue .example.org TRUE / FALSE 2147483647.123 novalue