diff --git a/src/FtpConnection.cc b/src/FtpConnection.cc index 0d64f52b..26d4dacb 100644 --- a/src/FtpConnection.cc +++ b/src/FtpConnection.cc @@ -406,9 +406,10 @@ int FtpConnection::receiveSizeResponse(int64_t& size) if(response.first == 213) { std::pair 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; diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc index 40181bd3..d7a313e6 100644 --- a/src/HttpHeader.cc +++ b/src/HttpHeader.cc @@ -93,9 +93,10 @@ RangeHandle HttpHeader::getRange() const if(clenStr.empty()) { return SharedHandle(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::max()) { throw DOWNLOAD_FAILURE_EXCEPTION (fmt(EX_TOO_LARGE_FILE, contentLength)); @@ -135,11 +136,12 @@ RangeHandle HttpHeader::getRange() const if(minus == slash) { return SharedHandle(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::max()) { diff --git a/src/OptionHandlerImpl.cc b/src/OptionHandlerImpl.cc index 86cc9d28..836c93f0 100644 --- a/src/OptionHandlerImpl.cc +++ b/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) diff --git a/src/RpcMethodImpl.cc b/src/RpcMethodImpl.cc index 34ab43a9..3a787e91 100644 --- a/src/RpcMethodImpl.cc +++ b/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 diff --git a/src/util.cc b/src/util.cc index 3fc7de10..c54b5ded 100644 --- a/src/util.cc +++ b/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& 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& 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 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(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)); } diff --git a/src/util.h b/src/util.h index d8abc39d..f7f6009d 100644 --- a/src/util.h +++ b/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& sgl, const std::string& src); diff --git a/test/GZipEncoderTest.cc b/test/GZipEncoderTest.cc index 8322d4a1..66f19f77 100644 --- a/test/GZipEncoderTest.cc +++ b/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(); diff --git a/test/UtilTest.cc b/test/UtilTest.cc index 705015bf..d6ac9d6e 100644 --- a/test/UtilTest.cc +++ b/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;