2007-11-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Replaced strtol with Util::parseInt
	* src/ChunkedEncoding.cc
	* src/HttpConnection.cc
	* src/CookieBoxFactory.cc
	* src/ParameterizedStringParser.cc
	* src/Util.cc
	* test/UtilTest.cc
	* test/OptionHandlerTest.cc
	* src/Request.cc

	Throw exception when empty string is given. The message for 
exception
	changed.
	* src/Util.cc (parseInt)(parseLLInt)
	* src/message.h
pull/1/head
Tatsuhiro Tsujikawa 2007-11-22 11:17:35 +00:00
parent 1fed0c0cb0
commit 7436490f75
11 changed files with 131 additions and 41 deletions

View File

@ -1,3 +1,20 @@
2007-11-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Replaced strtol with Util::parseInt
* src/ChunkedEncoding.cc
* src/HttpConnection.cc
* src/CookieBoxFactory.cc
* src/ParameterizedStringParser.cc
* src/Util.cc
* test/UtilTest.cc
* test/OptionHandlerTest.cc
* src/Request.cc
Throw exception when empty string is given. The message for exception
changed.
* src/Util.cc (parseInt)(parseLLInt)
* src/message.h
2007-11-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2007-11-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Set precision to 2 because share ratio is rounded into 1.0 if precision Set precision to 2 because share ratio is rounded into 1.0 if precision

2
TODO
View File

@ -53,7 +53,7 @@
DlAbortEx .... Abort download with the connection/url. Should be renamed to PermanentFailureException DlAbortEx .... Abort download with the connection/url. Should be renamed to PermanentFailureException
DownloadFailureException .... RequestGroup should halt. DownloadFailureException .... RequestGroup should halt.
FatalException .... Program should abort. FatalException .... Program should abort.
* replace strtol with Util::parseInt
-- remaining issues to be implemented for 0.12.0 release -- remaining issues to be implemented for 0.12.0 release
* Update translation * Update translation
* replace strtol with Util::parseInt

View File

@ -35,6 +35,7 @@
#include "ChunkedEncoding.h" #include "ChunkedEncoding.h"
#include "DlAbortEx.h" #include "DlAbortEx.h"
#include "message.h" #include "message.h"
#include "Util.h"
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <errno.h> #include <errno.h>
@ -155,23 +156,15 @@ int32_t ChunkedEncoding::readChunkSize(char** pp) {
return -1; return -1;
} }
p = rp; p = rp;
// We ignore chunk-extension // We ignore chunk-extension
char* exsp = (char*)memchr(*pp, ';', strbufTail-*pp); char* exsp = (char*)memchr(*pp, ';', strbufTail-*pp);
if(exsp == NULL) { if(exsp == 0 || p < exsp) {
exsp = p; exsp = p;
} }
// TODO check invalid characters in buffer string temp(*pp, exsp);
char* temp = new char[exsp-*pp+1]; chunkSize = Util::parseInt(temp, 16);
memcpy(temp, *pp, exsp-*pp);
temp[exsp-*pp] = '\0';
chunkSize = strtol(temp, NULL, 16);
delete [] temp;
if(chunkSize < 0) { if(chunkSize < 0) {
throw new DlAbortEx(EX_INVALID_CHUNK_SIZE); throw new DlAbortEx(EX_INVALID_CHUNK_SIZE);
} else if(errno == ERANGE && (chunkSize == INT32_MAX || chunkSize == INT32_MIN)) {
throw new DlAbortEx(strerror(errno));
} }
*pp = p+2; *pp = p+2;
return 0; return 0;

View File

@ -68,7 +68,7 @@ Cookie CookieBoxFactory::parseNsCookie(const string& nsCookieStr) const
c.domain = vs[0]; c.domain = vs[0];
c.path = vs[2]; c.path = vs[2];
c.secure = vs[3] == "TRUE" ? true : false; c.secure = vs[3] == "TRUE" ? true : false;
c.expires = strtol(vs[4].c_str(), NULL, 10); c.expires = Util::parseInt(vs[4]);
c.name = vs[5]; c.name = vs[5];
if(vs.size() >= 7) { if(vs.size() >= 7) {
c.value = vs[6]; c.value = vs[6];

View File

@ -115,7 +115,7 @@ HttpResponseHandle HttpConnection::receiveResponse()
HttpResponseHandle httpResponse = new HttpResponse(); HttpResponseHandle httpResponse = new HttpResponse();
httpResponse->setCuid(cuid); httpResponse->setCuid(cuid);
httpResponse->setStatus(strtol(httpStatusHeader.first.c_str(), 0, 10)); httpResponse->setStatus(Util::parseInt(httpStatusHeader.first));
httpResponse->setHttpHeader(httpStatusHeader.second); httpResponse->setHttpHeader(httpStatusHeader.second);
httpResponse->setHttpRequest(entry->getHttpRequest()); httpResponse->setHttpRequest(entry->getHttpRequest());

View File

@ -111,7 +111,7 @@ PStringDatumHandle ParameterizedStringParser::createLoop(const string& src,
if(colonIndex != string::npos) { if(colonIndex != string::npos) {
string stepStr = loopStr.substr(colonIndex+1); string stepStr = loopStr.substr(colonIndex+1);
if(Util::isNumber(stepStr)) { if(Util::isNumber(stepStr)) {
step = strtol(stepStr.c_str(), 0, 10); step = Util::parseInt(stepStr);
} else { } else {
throw new FatalException("A step count must be a number."); throw new FatalException("A step count must be a number.");
} }
@ -126,8 +126,8 @@ PStringDatumHandle ParameterizedStringParser::createLoop(const string& src,
int32_t end; int32_t end;
if(Util::isNumber(range.first) && Util::isNumber(range.second)) { if(Util::isNumber(range.first) && Util::isNumber(range.second)) {
nd = new FixedWidthNumberDecorator(range.first.size()); nd = new FixedWidthNumberDecorator(range.first.size());
start = strtol(range.first.c_str(), 0, 10); start = Util::parseInt(range.first);
end = strtol(range.second.c_str(), 0, 10); end = Util::parseInt(range.second);
} else if(Util::isLowercase(range.first) && Util::isLowercase(range.second)) { } else if(Util::isLowercase(range.first) && Util::isLowercase(range.second)) {
nd = new AlphaNumberDecorator(range.first.size()); nd = new AlphaNumberDecorator(range.first.size());
start = Util::alphaToNum(range.first); start = Util::alphaToNum(range.first);

View File

@ -36,6 +36,7 @@
#include "Util.h" #include "Util.h"
#include "FeatureConfig.h" #include "FeatureConfig.h"
#include "CookieBoxFactory.h" #include "CookieBoxFactory.h"
#include "RecoverableException.h"
const string Request::METHOD_GET = "get"; const string Request::METHOD_GET = "get";
@ -113,8 +114,13 @@ bool Request::parseUrl(const string& url) {
Util::split(hostAndPort, hostPart, ':'); Util::split(hostAndPort, hostPart, ':');
host = hostAndPort.first; host = hostAndPort.first;
if(hostAndPort.second != "") { if(hostAndPort.second != "") {
port = strtol(hostAndPort.second.c_str(), NULL, 10); try {
if(!(0 < port && port <= 65535)) { port = Util::parseInt(hostAndPort.second);
if(!(0 < port && port <= 65535)) {
return false;
}
} catch(RecoverableException* e) {
delete e;
return false; return false;
} }
} else { } else {

View File

@ -304,11 +304,7 @@ string Util::urldecode(const string& target) {
if(*itr == '%') { if(*itr == '%') {
if(itr+1 != target.end() && itr+2 != target.end() && if(itr+1 != target.end() && itr+2 != target.end() &&
isxdigit(*(itr+1)) && isxdigit(*(itr+2))) { isxdigit(*(itr+1)) && isxdigit(*(itr+2))) {
char temp[3]; result += Util::parseInt(string(itr+1, itr+3), 16);
temp[0] = *(itr+1);
temp[1] = *(itr+2);
temp[2] = '\0';
result += strtol(temp, 0, 16);
itr += 2; itr += 2;
} else { } else {
result += *itr; result += *itr;
@ -466,26 +462,38 @@ void Util::unfoldRange(const string& src, Integers& range) {
int32_t Util::parseInt(const string& s, int32_t base) int32_t Util::parseInt(const string& s, int32_t base)
{ {
if(s.empty()) {
throw new DlAbortEx(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"empty string");
}
char* stop; char* stop;
errno = 0; errno = 0;
long int v = strtol(s.c_str(), &stop, base); long int v = strtol(s.c_str(), &stop, base);
if(*stop != '\0') { if(*stop != '\0') {
throw new DlAbortEx(MSG_ILLEGAL_CHARACTER, stop); throw new DlAbortEx(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"illegal character");
} else if((v == LONG_MIN || v == LONG_MAX) && errno == ERANGE || v > INT32_MAX || v < INT32_MIN) { } else if((v == LONG_MIN || v == LONG_MAX) && errno == ERANGE || v > INT32_MAX || v < INT32_MIN) {
throw new DlAbortEx(MSG_OVERFLOW_UNDERFLOW_DETECTED, s.c_str()); throw new DlAbortEx(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"overflow/underflow");
} }
return v; return v;
} }
int64_t Util::parseLLInt(const string& s, int32_t base) int64_t Util::parseLLInt(const string& s, int32_t base)
{ {
if(s.empty()) {
throw new DlAbortEx(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"empty string");
}
char* stop; char* stop;
errno = 0; errno = 0;
int64_t v = strtoll(s.c_str(), &stop, base); int64_t v = strtoll(s.c_str(), &stop, base);
if(*stop != '\0') { if(*stop != '\0') {
throw new DlAbortEx(MSG_ILLEGAL_CHARACTER, stop); throw new DlAbortEx(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"illegal character");
} else if((v == INT64_MIN || v == INT64_MAX) && errno == ERANGE) { } else if((v == INT64_MIN || v == INT64_MAX) && errno == ERANGE) {
throw new DlAbortEx(MSG_OVERFLOW_UNDERFLOW_DETECTED, s.c_str()); throw new DlAbortEx(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"overflow/underflow");
} }
return v; return v;
} }
@ -646,7 +654,15 @@ int64_t Util::getRealSize(const string& sizeWithUnit)
} }
size = sizeWithUnit.substr(0, p); size = sizeWithUnit.substr(0, p);
} }
return strtoll(size.c_str(), 0, 10)*mult; int64_t v = Util::parseLLInt(size);
if(v < 0) {
throw new DlAbortEx("Negative value detected: %s", sizeWithUnit.c_str());
} else if(v*mult < 0) {
throw new DlAbortEx(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"overflow/underflow");
}
return v*mult;
} }
string Util::abbrevSize(int64_t size) string Util::abbrevSize(int64_t size)

View File

@ -126,9 +126,8 @@
#define MSG_DAEMON_FAILED _("daemon failed.") #define MSG_DAEMON_FAILED _("daemon failed.")
#define MSG_VERIFICATION_SUCCESSFUL _("Verification finished successfully. file=%s") #define MSG_VERIFICATION_SUCCESSFUL _("Verification finished successfully. file=%s")
#define MSG_VERIFICATION_FAILED _("Checksum error detected. file=%s") #define MSG_VERIFICATION_FAILED _("Checksum error detected. file=%s")
#define MSG_ILLEGAL_CHARACTER _("Illegal character detected: %s")
#define MSG_INCOMPLETE_RANGE _("Incomplete range specified. %s") #define MSG_INCOMPLETE_RANGE _("Incomplete range specified. %s")
#define MSG_OVERFLOW_UNDERFLOW_DETECTED _("Overflow/underflow detected: %s") #define MSG_STRING_INTEGER_CONVERSION_FAILURE _("Failed to convert string into value: %s")
#define EX_TIME_OUT _("Timeout.") #define EX_TIME_OUT _("Timeout.")
#define EX_INVALID_CHUNK_SIZE _("Invalid chunk size.") #define EX_INVALID_CHUNK_SIZE _("Invalid chunk size.")

View File

@ -151,12 +151,26 @@ void OptionHandlerTest::testUnitNumberOptionHandler()
CPPUNIT_ASSERT_EQUAL(string("4294967296"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(string("4294967296"), option.get("foo"));
handler.parse(&option, "4096K"); handler.parse(&option, "4096K");
CPPUNIT_ASSERT_EQUAL(string("4194304"), option.get("foo")); CPPUNIT_ASSERT_EQUAL(string("4194304"), option.get("foo"));
handler.parse(&option, "K"); try {
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo")); handler.parse(&option, "K");
handler.parse(&option, "M"); CPPUNIT_FAIL("exception must be thrown.");
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo")); } catch(Exception* e) {
handler.parse(&option, ""); cerr << *e;
CPPUNIT_ASSERT_EQUAL(string("0"), option.get("foo")); delete e;
}
try {
handler.parse(&option, "M");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
handler.parse(&option, "");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
} }
void OptionHandlerTest::testParameterOptionHandler_1argInit() void OptionHandlerTest::testParameterOptionHandler_1argInit()

View File

@ -305,8 +305,41 @@ void UtilTest::testGetRealSize()
{ {
CPPUNIT_ASSERT_EQUAL((int64_t)4294967296LL, Util::getRealSize("4096M")); CPPUNIT_ASSERT_EQUAL((int64_t)4294967296LL, Util::getRealSize("4096M"));
CPPUNIT_ASSERT_EQUAL((int64_t)1024, Util::getRealSize("1K")); CPPUNIT_ASSERT_EQUAL((int64_t)1024, Util::getRealSize("1K"));
CPPUNIT_ASSERT_EQUAL((int64_t)0, Util::getRealSize("")); try {
CPPUNIT_ASSERT_EQUAL((int64_t)0, Util::getRealSize("foo")); Util::getRealSize("");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
Util::getRealSize("foo");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
Util::getRealSize("-1");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
Util::getRealSize("9223372036854775807K");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
try {
Util::getRealSize("9223372036854775807M");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
} }
void UtilTest::testAbbrevSize() void UtilTest::testAbbrevSize()
@ -504,7 +537,13 @@ void UtilTest::testParseInt()
cerr << *e; cerr << *e;
delete e; delete e;
} }
try {
Util::parseInt("");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
} }
void UtilTest::testParseLLInt() void UtilTest::testParseLLInt()
@ -533,5 +572,11 @@ void UtilTest::testParseLLInt()
cerr << *e; cerr << *e;
delete e; delete e;
} }
try {
Util::parseLLInt("");
CPPUNIT_FAIL("exception must be thrown.");
} catch(Exception* e) {
cerr << *e;
delete e;
}
} }