Kaynağa Gözat

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

Tatsuhiro Tsujikawa 9 yıl önce
ebeveyn
işleme
bafbbe7c1d

+ 8 - 3
src/NsCookieParser.cc

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

+ 27 - 0
src/util.cc

@@ -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> sgl;

+ 4 - 0
src/util.h

@@ -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);
 
+// 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);
 
 // Parses string which specifies the range of piece index for higher

+ 2 - 2
test/CookieStorageTest.cc

@@ -328,10 +328,10 @@ void CookieStorageTest::testLoad()
   c = cookies[3];
   CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName());
   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_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());
 }
 

+ 2 - 2
test/NsCookieParserTest.cc

@@ -69,9 +69,9 @@ void NsCookieParserTest::testParse()
   c = cookies[3].get();
   CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName());
   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_EQUAL(std::string("overflow"), c->getDomain());
+  CPPUNIT_ASSERT_EQUAL(std::string("something"), c->getDomain());
   CPPUNIT_ASSERT(c->getHostOnly());
   CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath());
   CPPUNIT_ASSERT(!c->getSecure());

+ 19 - 0
test/UtilTest2.cc

@@ -66,6 +66,7 @@ class UtilTest2 : public CppUnit::TestFixture {
   CPPUNIT_TEST(testInPrivateAddress);
   CPPUNIT_TEST(testSecfmt);
   CPPUNIT_TEST(testTlsHostnameMatch);
+  CPPUNIT_TEST(testParseDoubleNoThrow);
   CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -115,6 +116,7 @@ public:
   void testInPrivateAddress();
   void testSecfmt();
   void testTlsHostnameMatch();
+  void testParseDoubleNoThrow();
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(UtilTest2);
@@ -978,4 +980,21 @@ void UtilTest2::testTlsHostnameMatch()
   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

+ 2 - 2
test/nscookietest.txt

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