Remove exceptions from s3fs_strtoofft

Explicit return codes are simpler and safer.
This commit is contained in:
Andrew Gaul 2020-10-02 10:23:56 +09:00
parent 757f4caee8
commit 3628b9d1e2
6 changed files with 47 additions and 51 deletions

View File

@ -33,7 +33,7 @@ AC_CHECK_HEADERS([sys/xattr.h])
AC_CHECK_HEADERS([attr/xattr.h])
AC_CHECK_HEADERS([sys/extattr.h])
CXXFLAGS="$CXXFLAGS -Wall -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2"
CXXFLAGS="$CXXFLAGS -Wall -fno-exceptions -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2"
dnl ----------------------------------------------
dnl For macOS

View File

@ -1133,7 +1133,7 @@ S3fsCurl* S3fsCurl::UploadMultipartPostRetryCallback(S3fsCurl* s3fscurl)
if(!get_keyword_value(s3fscurl->url, "partNumber", part_num_str)){
return NULL;
}
if(!try_strtoofft(part_num_str.c_str(), tmp_part_num, /*base=*/ 10)){
if(!s3fs_strtoofft(&tmp_part_num, part_num_str.c_str(), /*base=*/ 10)){
return NULL;
}
part_num = static_cast<off_t>(tmp_part_num);
@ -1181,7 +1181,7 @@ S3fsCurl* S3fsCurl::CopyMultipartPostRetryCallback(S3fsCurl* s3fscurl)
if(!get_keyword_value(s3fscurl->url, "partNumber", part_num_str)){
return NULL;
}
if(!try_strtoofft(part_num_str.c_str(), tmp_part_num, /*base=*/ 10)){
if(!s3fs_strtoofft(&tmp_part_num, part_num_str.c_str(), /*base=*/ 10)){
return NULL;
}
part_num = static_cast<off_t>(tmp_part_num);
@ -1666,7 +1666,7 @@ bool S3fsCurl::SetIAMCredentials(const char* response)
if(S3fsCurl::is_ibm_iam_auth){
off_t tmp_expire = 0;
if(!try_strtoofft(keyval[std::string(S3fsCurl::IAM_expiry_field)].c_str(), tmp_expire, /*base=*/ 10)){
if(!s3fs_strtoofft(&tmp_expire, keyval[std::string(S3fsCurl::IAM_expiry_field)].c_str(), /*base=*/ 10)){
return false;
}
S3fsCurl::AWSAccessTokenExpire = static_cast<time_t>(tmp_expire);

View File

@ -60,51 +60,30 @@ template std::string str(unsigned long long value);
//-------------------------------------------------------------------
static const char hexAlphabet[] = "0123456789ABCDEF";
// replacement for C++11 std::stoll
off_t s3fs_strtoofft(const char* str, int base)
bool s3fs_strtoofft(off_t* value, const char* str, int base)
{
if(value == NULL || str == NULL){
return false;
}
errno = 0;
char *temp;
long long result = strtoll(str, &temp, base);
if(temp == str || *temp != '\0'){
throw std::invalid_argument("s3fs_strtoofft");
}
if((result == LLONG_MIN || result == LLONG_MAX) && errno == ERANGE){
throw std::out_of_range("s3fs_strtoofft");
}
return result;
}
// wrapped s3fs_strtoofft()
//
// This function catches the s3fs_strtoofft () exception and returns a boolean value.
//
bool try_strtoofft(const char* str, off_t& value, int base)
{
if(str){
try{
value = s3fs_strtoofft(str, base);
}catch(std::exception &e){
S3FS_PRN_WARN("something error is occurred in convert std::string(%s) to off_t.", str);
return false;
}
}else{
S3FS_PRN_WARN("parameter std::string is null.");
return false;
}
if((result == LLONG_MIN || result == LLONG_MAX) && errno == ERANGE){
return false;
}
*value = result;
return true;
}
// wrapped try_strtoofft -> s3fs_strtoofft()
//
// This function returns 0 if a value that cannot be converted is specified.
// Only call if 0 is considered an error and the operation can continue.
//
off_t cvt_strtoofft(const char* str, int base)
{
off_t result = 0;
if(!try_strtoofft(str, result, base)){
if(!s3fs_strtoofft(&result, str, base)){
S3FS_PRN_WARN("something error is occurred in convert std::string(%s) to off_t, thus return 0 as default.", (str ? str : "null"));
return 0;
}

View File

@ -55,10 +55,14 @@ template <class T> std::string str(T value);
// Utilities
//-------------------------------------------------------------------
//
// Convert string to off_t. Throws std::invalid_argument and std::out_of_range on bad input.
// Convert string to off_t. Returns false on bad input.
// Replacement for C++11 std::stoll.
//
bool s3fs_strtoofft(off_t* value, const char* str, int base = 0);
//
// This function returns 0 if a value that cannot be converted is specified.
// Only call if 0 is considered an error and the operation can continue.
//
off_t s3fs_strtoofft(const char* str, int base = 0);
bool try_strtoofft(const char* str, off_t& value, int base = 0);
off_t cvt_strtoofft(const char* str, int base = 0);
//

View File

@ -89,19 +89,30 @@ void test_base64()
void test_strtoofft()
{
ASSERT_EQUALS(s3fs_strtoofft("0"), static_cast<off_t>(0L));
ASSERT_EQUALS(s3fs_strtoofft("9"), static_cast<off_t>(9L));
try{
s3fs_strtoofft("A");
abort();
}catch(std::exception &e){
// expected
}
ASSERT_EQUALS(s3fs_strtoofft("A", /*base=*/ 16), static_cast<off_t>(10L));
ASSERT_EQUALS(s3fs_strtoofft("F", /*base=*/ 16), static_cast<off_t>(15L));
ASSERT_EQUALS(s3fs_strtoofft("a", /*base=*/ 16), static_cast<off_t>(10L));
ASSERT_EQUALS(s3fs_strtoofft("f", /*base=*/ 16), static_cast<off_t>(15L));
ASSERT_EQUALS(s3fs_strtoofft("deadbeef", /*base=*/ 16), static_cast<off_t>(3735928559L));
off_t value;
ASSERT_TRUE(s3fs_strtoofft(&value, "0"));
ASSERT_EQUALS(value, static_cast<off_t>(0L));
ASSERT_TRUE(s3fs_strtoofft(&value, "9"));
ASSERT_EQUALS(value, static_cast<off_t>(9L));
ASSERT_FALSE(s3fs_strtoofft(&value, "A"));
ASSERT_TRUE(s3fs_strtoofft(&value, "A", /*base=*/ 16));
ASSERT_EQUALS(value, static_cast<off_t>(10L));
ASSERT_TRUE(s3fs_strtoofft(&value, "F", /*base=*/ 16));
ASSERT_EQUALS(value, static_cast<off_t>(15L));
ASSERT_TRUE(s3fs_strtoofft(&value, "a", /*base=*/ 16));
ASSERT_EQUALS(value, static_cast<off_t>(10L));
ASSERT_TRUE(s3fs_strtoofft(&value, "f", /*base=*/ 16));
ASSERT_EQUALS(value, static_cast<off_t>(15L));
ASSERT_TRUE(s3fs_strtoofft(&value, "deadbeef", /*base=*/ 16));
ASSERT_EQUALS(value, static_cast<off_t>(3735928559L));
}
void test_wtf8_encoding()

View File

@ -74,6 +74,8 @@ void assert_strequals(const char *x, const char *y, const char *file, int line)
}
}
#define ASSERT_TRUE(x) assert_equals((x), true, __FILE__, __LINE__)
#define ASSERT_FALSE(x) assert_equals((x), false, __FILE__, __LINE__)
#define ASSERT_EQUALS(x, y) assert_equals((x), (y), __FILE__, __LINE__)
#define ASSERT_NEQUALS(x, y) assert_nequals((x), (y), __FILE__, __LINE__)
#define ASSERT_STREQUALS(x, y) assert_strequals((x), (y), __FILE__, __LINE__)