Browse Source

Use nothrow version of parseInt, parseUInt and parseLLInt

Tatsuhiro Tsujikawa 13 years ago
parent
commit
89f18dde85
8 changed files with 51 additions and 167 deletions
  1. 4 3
      src/FtpConnection.cc
  2. 10 8
      src/HttpHeader.cc
  3. 6 1
      src/OptionHandlerImpl.cc
  4. 6 1
      src/RpcMethodImpl.cc
  5. 23 49
      src/util.cc
  6. 0 3
      src/util.h
  7. 2 2
      test/GZipEncoderTest.cc
  8. 0 100
      test/UtilTest.cc

+ 4 - 3
src/FtpConnection.cc

@@ -406,9 +406,10 @@ int FtpConnection::receiveSizeResponse(int64_t& size)
     if(response.first == 213) {
       std::pair<Sip, Sip> rp;
       util::divide(rp, response.second.begin(), response.second.end(), ' ');
-      size = util::parseLLInt(std::string(rp.second.first, rp.second.second));
-      if(size < 0) {
-        throw DL_ABORT_EX("Size must be positive");
+      if(!util::parseLLIntNoThrow(size, std::string(rp.second.first,
+                                                    rp.second.second)) ||
+         size < 0) {
+        throw DL_ABORT_EX("Size must be positive integer");
       }
     }
     return response.first;

+ 10 - 8
src/HttpHeader.cc

@@ -93,9 +93,10 @@ RangeHandle HttpHeader::getRange() const
     if(clenStr.empty()) {
       return SharedHandle<Range>(new Range());
     } else {
-      int64_t contentLength = util::parseLLInt(clenStr);
-      if(contentLength < 0) {
-        throw DL_ABORT_EX("Content-Length must be positive");
+      int64_t contentLength;
+      if(!util::parseLLIntNoThrow(contentLength, clenStr) ||
+         contentLength < 0) {
+        throw DL_ABORT_EX("Content-Length must be positive integer");
       } else if(contentLength > std::numeric_limits<off_t>::max()) {
         throw DOWNLOAD_FAILURE_EXCEPTION
           (fmt(EX_TOO_LARGE_FILE, contentLength));
@@ -135,11 +136,12 @@ RangeHandle HttpHeader::getRange() const
   if(minus == slash) {
     return SharedHandle<Range>(new Range());
   }
-  int64_t startByte = util::parseLLInt(std::string(byteRangeSpec, minus));
-  int64_t endByte = util::parseLLInt(std::string(minus+1, slash));
-  int64_t entityLength =
-    util::parseLLInt(std::string(slash+1, rangeStr.end()));
-  if(startByte < 0 || endByte < 0 || entityLength < 0) {
+  int64_t startByte, endByte, entityLength;
+  if(!util::parseLLIntNoThrow(startByte, std::string(byteRangeSpec, minus)) ||
+     !util::parseLLIntNoThrow(endByte, std::string(minus+1, slash)) ||
+     !util::parseLLIntNoThrow(entityLength,
+                              std::string(slash+1, rangeStr.end())) ||
+     startByte < 0 || endByte < 0 || entityLength < 0) {
     throw DL_ABORT_EX("byte-range-spec must be positive");
   }
   if(startByte > std::numeric_limits<off_t>::max()) {

+ 6 - 1
src/OptionHandlerImpl.cc

@@ -154,7 +154,12 @@ NumberOptionHandler::~NumberOptionHandler() {}
 
 void NumberOptionHandler::parseArg(Option& option, const std::string& optarg)
 {
-  parseArg(option, util::parseLLInt(optarg));
+  int64_t number;
+  if(util::parseLLIntNoThrow(number, optarg)) {
+    parseArg(option, number);
+  } else {
+    throw DL_ABORT_EX(fmt("Bad number %s", optarg.c_str()));
+  }
 }
 
 void NumberOptionHandler::parseArg(Option& option, int64_t number)

+ 6 - 1
src/RpcMethodImpl.cc

@@ -185,7 +185,12 @@ namespace {
 a2_gid_t str2Gid(const String* str)
 {
   assert(str);
-  return util::parseLLInt(str->s());
+  int64_t gid;
+  if(util::parseLLIntNoThrow(gid, str->s())) {
+    return gid;
+  } else {
+    throw DL_ABORT_EX(fmt("Bad GID %s", str->s().c_str()));
+  }
 }
 } // namespace
 

+ 23 - 49
src/util.cc

@@ -458,7 +458,7 @@ std::string percentDecode
     if(*first == '%') {
       if(first+1 != last && first+2 != last &&
          isHexDigit(*(first+1)) && isHexDigit(*(first+2))) {
-        result += parseInt(std::string(first+1, first+3), 16);
+        result += hexCharToUInt(*(first+1))*16+hexCharToUInt(*(first+2));
         first += 2;
       } else {
         result += *first;
@@ -596,18 +596,6 @@ bool parseIntNoThrow(int32_t& res, const std::string& s, int base)
   }
 }
 
-int32_t parseInt(const std::string& s, int base)
-{
-  int32_t res;
-  if(parseIntNoThrow(res, s, base)) {
-    return res;
-  } else {
-    throw DL_ABORT_EX
-      (fmt("Failed to convert string into 32bit signed integer. '%s'",
-           s.c_str()));
-  }
-}
-
 bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base)
 {
   long int t;
@@ -621,18 +609,6 @@ bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base)
   }
 }
 
-uint32_t parseUInt(const std::string& s, int base)
-{
-  uint32_t res;
-  if(parseUIntNoThrow(res, s, base)) {
-    return res;
-  } else {
-    throw DL_ABORT_EX
-      (fmt("Failed to convert string into 32bit unsigned integer. '%s'",
-           s.c_str()));
-  }
-}
-
 bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base)
 {
   long long int t;
@@ -646,18 +622,6 @@ bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base)
   }
 }
 
-int64_t parseLLInt(const std::string& s, int base)
-{
-  int64_t res;
-  if(parseLLIntNoThrow(res, s, base)) {
-    return res;
-  } else {
-    throw DL_ABORT_EX
-      (fmt("Failed to convert string into 64bit signed integer. '%s'",
-           s.c_str()));
-  }
-}
-
 void parseIntSegments(SegList<int>& sgl, const std::string& src)
 {
   for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi;) {
@@ -668,14 +632,22 @@ void parseIntSegments(SegList<int>& sgl, const std::string& src)
     }
     std::string::const_iterator p = std::find(i, j, '-');
     if(p == j) {
-      int a = parseInt(std::string(i, j));
-      sgl.add(a, a+1);
+      int a;
+      if(parseIntNoThrow(a, std::string(i, j))) {
+        sgl.add(a, a+1);
+      } else {
+        throw DL_ABORT_EX(fmt("Bad range %s", std::string(i, j).c_str()));
+      }
     } else if(p == i || p+1 == j) {
       throw DL_ABORT_EX(fmt(MSG_INCOMPLETE_RANGE, std::string(i, j).c_str()));
     } else {
-      int a = parseInt(std::string(i, p));
-      int b = parseInt(std::string(p+1, j));
-      sgl.add(a, b+1);
+      int a, b;
+      if(parseIntNoThrow(a, std::string(i, p)) &&
+         parseIntNoThrow(b, (std::string(p+1, j)))) {
+        sgl.add(a, b+1);
+      } else {
+        throw DL_ABORT_EX(fmt("Bad range %s", std::string(i, j).c_str()));
+      }
     }
     if(j == eoi) {
       break;
@@ -1062,10 +1034,10 @@ int64_t getRealSize(const std::string& sizeWithUnit)
     }
     size.assign(sizeWithUnit.begin(), sizeWithUnit.begin()+p);
   }
-  int64_t v = parseLLInt(size);
-
-  if(v < 0) {
-    throw DL_ABORT_EX(fmt("Negative value detected: %s", sizeWithUnit.c_str()));
+  int64_t v;
+  if(!parseLLIntNoThrow(v, size) || v < 0) {
+    throw DL_ABORT_EX(fmt("Bad or negative value detected: %s",
+                          sizeWithUnit.c_str()));
   } else if(INT64_MAX/mult < v) {
     throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
                           "overflow/underflow"));
@@ -1260,10 +1232,12 @@ parseIndexPath(const std::string& line)
 {
   std::pair<Scip, Scip> p;
   divide(p, line.begin(), line.end(), '=');
-  size_t index = parseUInt(std::string(p.first.first, p.first.second));
+  uint32_t index;
+  if(!parseUIntNoThrow(index, std::string(p.first.first, p.first.second))) {
+    throw DL_ABORT_EX("Bad path index");
+  }
   if(p.second.first == p.second.second) {
-    throw DL_ABORT_EX(fmt("Path with index=%u is empty.",
-                          static_cast<unsigned int>(index)));
+    throw DL_ABORT_EX(fmt("Path with index=%u is empty.", index));
   }
   return std::make_pair(index, std::string(p.second.first, p.second.second));
 }

+ 0 - 3
src/util.h

@@ -262,14 +262,11 @@ bool isPowerOf(int num, int base);
 std::string secfmt(time_t sec);
 
 bool parseIntNoThrow(int32_t& res, const std::string& s, int base = 10);
-int32_t parseInt(const std::string& s, int base = 10);
 
 // Valid range: [0, INT32_MAX]
 bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base = 10);
-uint32_t parseUInt(const std::string& s, int base = 10);
 
 bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base = 10);
-int64_t parseLLInt(const std::string& s, int base = 10);
 
 void parseIntSegments(SegList<int>& sgl, const std::string& src);
 

+ 2 - 2
test/GZipEncoderTest.cc

@@ -28,9 +28,9 @@ void GZipEncoderTest::testEncode()
   inputs.push_back("Hello World");
   inputs.push_back("9223372036854775807");
   inputs.push_back("Fox");
-  
+
   encoder << inputs[0];
-  encoder << util::parseLLInt(inputs[1]);
+  encoder << (int64_t)9223372036854775807LL;
   encoder << inputs[2].c_str();
 
   std::string gzippedData = encoder.str();

+ 0 - 100
test/UtilTest.cc

@@ -57,9 +57,6 @@ class UtilTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testConvertBitfield);
   CPPUNIT_TEST(testParseIntSegments);
   CPPUNIT_TEST(testParseIntSegments_invalidRange);
-  CPPUNIT_TEST(testParseInt);
-  CPPUNIT_TEST(testParseUInt);
-  CPPUNIT_TEST(testParseLLInt);
   CPPUNIT_TEST(testParseIntNoThrow);
   CPPUNIT_TEST(testParseUIntNoThrow);
   CPPUNIT_TEST(testParseLLIntNoThrow);
@@ -129,9 +126,6 @@ public:
   void testConvertBitfield();
   void testParseIntSegments();
   void testParseIntSegments_invalidRange();
-  void testParseInt();
-  void testParseUInt();
-  void testParseLLInt();
   void testParseIntNoThrow();
   void testParseUIntNoThrow();
   void testParseLLIntNoThrow();
@@ -1259,100 +1253,6 @@ void UtilTest::testParseIntSegments_invalidRange()
   }
 }
 
-void UtilTest::testParseInt()
-{
-  std::string s;
-  s = " -1 ";
-  CPPUNIT_ASSERT_EQUAL(-1, util::parseInt(s));
-  s = "2147483647";
-  CPPUNIT_ASSERT_EQUAL(2147483647, util::parseInt(s));
-  try {
-    s = "2147483648";
-    util::parseInt(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-  }
-  try {
-    s = "-2147483649";
-    util::parseInt(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-  }
-  try {
-    s = "12x";
-    util::parseInt(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-  }
-  try {
-    s = "";
-    util::parseInt(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-  }
-}
-
-void UtilTest::testParseUInt()
-{
-  std::string s;
-  s = " 2147483647 ";
-  CPPUNIT_ASSERT_EQUAL(2147483647U, util::parseUInt(s));
-  try {
-    s = "-1";
-    util::parseUInt(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-  }
-  try {
-    s = "2147483648";
-    util::parseUInt(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-  }
-}
-
-void UtilTest::testParseLLInt()
-{
-  std::string s;
-  {
-    s = " -1 ";
-    CPPUNIT_ASSERT_EQUAL((int64_t)-1LL, util::parseLLInt(s));
-  }
-  {
-    s = "9223372036854775807";
-    CPPUNIT_ASSERT_EQUAL((int64_t)9223372036854775807LL,
-                         util::parseLLInt(s));
-  }
-  try {
-    s = "9223372036854775808";
-    util::parseLLInt(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-    std::cerr << e.stackTrace();
-  }
-  try {
-    s = "-9223372036854775809";
-    util::parseLLInt(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-    std::cerr << e.stackTrace();
-  }
-  try {
-    s = "12x";
-    util::parseLLInt(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-    std::cerr << e.stackTrace();
-  }
-  try {
-    s = "";
-    util::parseLLInt(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(Exception& e) {
-    std::cerr << e.stackTrace();
-  }
-}
-
 void UtilTest::testParseIntNoThrow()
 {
   std::string s;