mirror of https://github.com/aria2/aria2
				
				
				
			Use nothrow version of parseInt, parseUInt and parseLLInt
							parent
							
								
									a879d75aaa
								
							
						
					
					
						commit
						89f18dde85
					
				| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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()) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										72
									
								
								src/util.cc
								
								
								
								
							
							
						
						
									
										72
									
								
								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));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										100
									
								
								test/UtilTest.cc
								
								
								
								
							
							
						
						
									
										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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue