Not abort process by exception threw from s3fs_strtoofft

This commit is contained in:
Takeshi Nakatani 2020-05-03 08:08:28 +00:00
parent 6e134a23f9
commit 97c249d5b9
7 changed files with 91 additions and 59 deletions

View File

@ -1375,13 +1375,17 @@ S3fsCurl* S3fsCurl::UploadMultipartPostRetryCallback(S3fsCurl* s3fscurl)
string upload_id;
string part_num_str;
int part_num;
off_t tmp_part_num = 0;
if(!get_keyword_value(s3fscurl->url, "uploadId", upload_id)){
return NULL;
}
if(!get_keyword_value(s3fscurl->url, "partNumber", part_num_str)){
return NULL;
}
part_num = s3fs_strtoofft(part_num_str.c_str(), /*base=*/ 10);
if(!try_strtoofft(part_num_str.c_str(), tmp_part_num, /*base=*/ 10)){
return NULL;
}
part_num = static_cast<off_t>(tmp_part_num);
if(s3fscurl->retry_count >= S3fsCurl::retries){
S3FS_PRN_ERR("Over retry count(%d) limit(%s:%d).", s3fscurl->retry_count, s3fscurl->path.c_str(), part_num);
@ -1419,13 +1423,17 @@ S3fsCurl* S3fsCurl::CopyMultipartPostRetryCallback(S3fsCurl* s3fscurl)
string upload_id;
string part_num_str;
int part_num;
off_t tmp_part_num = 0;
if(!get_keyword_value(s3fscurl->url, "uploadId", upload_id)){
return NULL;
}
if(!get_keyword_value(s3fscurl->url, "partNumber", part_num_str)){
return NULL;
}
part_num = s3fs_strtoofft(part_num_str.c_str(), /*base=*/ 10);
if(!try_strtoofft(part_num_str.c_str(), tmp_part_num, /*base=*/ 10)){
return NULL;
}
part_num = static_cast<off_t>(tmp_part_num);
if(s3fscurl->retry_count >= S3fsCurl::retries){
S3FS_PRN_ERR("Over retry count(%d) limit(%s:%d).", s3fscurl->retry_count, s3fscurl->path.c_str(), part_num);
@ -1921,7 +1929,11 @@ bool S3fsCurl::SetIAMCredentials(const char* response)
S3fsCurl::AWSAccessToken = keyval[string(S3fsCurl::IAM_token_field)];
if(S3fsCurl::is_ibm_iam_auth){
S3fsCurl::AWSAccessTokenExpire = s3fs_strtoofft(keyval[string(S3fsCurl::IAM_expiry_field)].c_str(), /*base=*/ 10);
off_t tmp_expire = 0;
if(!try_strtoofft(keyval[string(S3fsCurl::IAM_expiry_field)].c_str(), tmp_expire, /*base=*/ 10)){
return false;
}
S3fsCurl::AWSAccessTokenExpire = static_cast<time_t>(tmp_expire);
}else{
S3fsCurl::AWSAccessKeyId = keyval[string(IAMCRED_ACCESSKEYID)];
S3fsCurl::AWSSecretAccessKey = keyval[string(IAMCRED_SECRETACCESSKEY)];

View File

@ -62,33 +62,6 @@ static const int MAX_MULTIPART_CNT = 10 * 1000; // S3 multipart max count
#define TMPFILE_DIR_0PATH "/tmp"
#endif
//------------------------------------------------
// Local utility function
//------------------------------------------------
// Wrapped s3fs_strtoofft()
//
// PageList::Serialize method uses s3fs_strtoofft function,
// but s3fs_strtoofft throws an exception, so wrap it in
// this function.
// PageList::Serialize works as 0 when the read data is invalid.
//
static off_t wrap_strtoofft(const char* str)
{
off_t result;
if(str){
try{
result = s3fs_strtoofft(str);
}catch(std::exception &e){
S3FS_PRN_WARN("something error is occurred in convert string to off_t, so return 0 as default.");
result = 0;
}
}else{
S3FS_PRN_WARN("parameter is null, so return 0 as default.");
result = 0;
}
return result;
}
//------------------------------------------------
// CacheFileStat class methods
//------------------------------------------------
@ -931,12 +904,12 @@ bool PageList::Serialize(CacheFileStat& file, bool is_output, ino_t inode)
// get second part in head line.
if(!getline(sshead, strhead2, ':')){
// old head format is "<size>\n"
total = wrap_strtoofft(strhead1.c_str());
total = cvt_strtoofft(strhead1.c_str(), /* base= */10);
cache_inode = 0;
}else{
// current head format is "<inode>:<size>\n"
total = wrap_strtoofft(strhead1.c_str());
cache_inode = static_cast<ino_t>(wrap_strtoofft(strhead2.c_str()));
total = cvt_strtoofft(strhead1.c_str(), /* base= */10);
cache_inode = static_cast<ino_t>(cvt_strtoofft(strhead2.c_str(), /* base= */10));
if(0 == cache_inode){
S3FS_PRN_ERR("wrong inode number in parsed cache stats.");
delete[] ptmp;
@ -961,24 +934,24 @@ bool PageList::Serialize(CacheFileStat& file, bool is_output, ino_t inode)
is_err = true;
break;
}
off_t offset = wrap_strtoofft(part.c_str());
off_t offset = cvt_strtoofft(part.c_str(), /* base= */10);
// size
if(!getline(ssparts, part, ':')){
is_err = true;
break;
}
off_t size = wrap_strtoofft(part.c_str());
off_t size = cvt_strtoofft(part.c_str(), /* base= */10);
// loaded
if(!getline(ssparts, part, ':')){
is_err = true;
break;
}
bool is_loaded = (1 == wrap_strtoofft(part.c_str()) ? true : false);
bool is_loaded = (1 == cvt_strtoofft(part.c_str(), /* base= */10) ? true : false);
bool is_modified;
if(!getline(ssparts, part, ':')){
is_modified = false; // old version does not have this part.
}else{
is_modified = (1 == wrap_strtoofft(part.c_str()) ? true : false);
is_modified = (1 == cvt_strtoofft(part.c_str(), /* base= */10) ? true : false);
}
// add new area
PageList::page_status pstatus =

View File

@ -4536,7 +4536,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 1; // continue for fuse option
}
if(0 == STR2NCMP(arg, "umask=")){
s3fs_umask = s3fs_strtoofft(strchr(arg, '=') + sizeof(char), /*base=*/ 8);
s3fs_umask = cvt_strtoofft(strchr(arg, '=') + sizeof(char), /*base=*/ 8);
s3fs_umask &= (S_IRWXU | S_IRWXG | S_IRWXO);
is_s3fs_umask = true;
return 1; // continue for fuse option
@ -4546,7 +4546,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 1; // continue for fuse option
}
if(0 == STR2NCMP(arg, "mp_umask=")){
mp_umask = s3fs_strtoofft(strchr(arg, '=') + sizeof(char), /*base=*/ 8);
mp_umask = cvt_strtoofft(strchr(arg, '=') + sizeof(char), /*base=*/ 8);
mp_umask &= (S_IRWXU | S_IRWXG | S_IRWXO);
is_mp_umask = true;
return 0;
@ -4562,7 +4562,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
if(0 == STR2NCMP(arg, "retries=")){
S3fsCurl::SetRetries(static_cast<int>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))));
S3fsCurl::SetRetries(static_cast<int>(cvt_strtoofft(strchr(arg, '=') + sizeof(char))));
return 0;
}
if(0 == STR2NCMP(arg, "use_cache=")){
@ -4578,7 +4578,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
if(0 == STR2NCMP(arg, "multireq_max=")){
int maxreq = static_cast<int>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)));
int maxreq = static_cast<int>(cvt_strtoofft(strchr(arg, '=') + sizeof(char)));
S3fsCurl::SetMaxMultiRequest(maxreq);
return 0;
}
@ -4595,7 +4595,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
off_t rrs = 1;
// for an old format.
if(0 == STR2NCMP(arg, "use_rrs=")){
rrs = s3fs_strtoofft(strchr(arg, '=') + sizeof(char));
rrs = cvt_strtoofft(strchr(arg, '=') + sizeof(char));
}
if(0 == rrs){
S3fsCurl::SetStorageClass(STANDARD);
@ -4735,7 +4735,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
if(0 == STR2NCMP(arg, "ssl_verify_hostname=")){
long sslvh = static_cast<long>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)));
long sslvh = static_cast<long>(cvt_strtoofft(strchr(arg, '=') + sizeof(char)));
if(-1 == S3fsCurl::SetSslVerifyHostname(sslvh)){
S3FS_PRN_EXIT("poorly formed argument to option: ssl_verify_hostname.");
return -1;
@ -4804,7 +4804,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
if(0 == STR2NCMP(arg, "public_bucket=")){
off_t pubbucket = s3fs_strtoofft(strchr(arg, '=') + sizeof(char));
off_t pubbucket = cvt_strtoofft(strchr(arg, '=') + sizeof(char));
if(1 == pubbucket){
S3fsCurl::SetPublicBucket(true);
// [NOTE]
@ -4832,17 +4832,17 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
if(0 == STR2NCMP(arg, "connect_timeout=")){
long contimeout = static_cast<long>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)));
long contimeout = static_cast<long>(cvt_strtoofft(strchr(arg, '=') + sizeof(char)));
S3fsCurl::SetConnectTimeout(contimeout);
return 0;
}
if(0 == STR2NCMP(arg, "readwrite_timeout=")){
time_t rwtimeout = static_cast<time_t>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)));
time_t rwtimeout = static_cast<time_t>(cvt_strtoofft(strchr(arg, '=') + sizeof(char)));
S3fsCurl::SetReadwriteTimeout(rwtimeout);
return 0;
}
if(0 == STR2NCMP(arg, "list_object_max_keys=")){
int max_keys = static_cast<int>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)));
int max_keys = static_cast<int>(cvt_strtoofft(strchr(arg, '=') + sizeof(char)));
if(max_keys < 1000){
S3FS_PRN_EXIT("argument should be over 1000: list_object_max_keys");
return -1;
@ -4851,19 +4851,19 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
if(0 == STR2NCMP(arg, "max_stat_cache_size=")){
unsigned long cache_size = static_cast<unsigned long>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)));
unsigned long cache_size = static_cast<unsigned long>(cvt_strtoofft(strchr(arg, '=') + sizeof(char)));
StatCache::getStatCacheData()->SetCacheSize(cache_size);
return 0;
}
if(0 == STR2NCMP(arg, "stat_cache_expire=")){
time_t expr_time = static_cast<time_t>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)));
time_t expr_time = static_cast<time_t>(cvt_strtoofft(strchr(arg, '=') + sizeof(char)));
StatCache::getStatCacheData()->SetExpireTime(expr_time);
return 0;
}
// [NOTE]
// This option is for compatibility old version.
if(0 == STR2NCMP(arg, "stat_cache_interval_expire=")){
time_t expr_time = static_cast<time_t>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)));
time_t expr_time = static_cast<time_t>(cvt_strtoofft(strchr(arg, '=') + sizeof(char)));
StatCache::getStatCacheData()->SetExpireTime(expr_time, true);
return 0;
}
@ -4880,7 +4880,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
if(0 == STR2NCMP(arg, "parallel_count=") || 0 == STR2NCMP(arg, "parallel_upload=")){
int maxpara = static_cast<int>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)));
int maxpara = static_cast<int>(cvt_strtoofft(strchr(arg, '=') + sizeof(char)));
if(0 >= maxpara){
S3FS_PRN_EXIT("argument should be over 1: parallel_count");
return -1;
@ -4893,7 +4893,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
if(0 == STR2NCMP(arg, "multipart_size=")){
off_t size = static_cast<off_t>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)));
off_t size = static_cast<off_t>(cvt_strtoofft(strchr(arg, '=') + sizeof(char)));
if(!S3fsCurl::SetMultipartSize(size)){
S3FS_PRN_EXIT("multipart_size option must be at least 5 MB.");
return -1;
@ -4901,7 +4901,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
if(0 == STR2NCMP(arg, "ensure_diskfree=")){
off_t dfsize = s3fs_strtoofft(strchr(arg, '=') + sizeof(char)) * 1024 * 1024;
off_t dfsize = cvt_strtoofft(strchr(arg, '=') + sizeof(char)) * 1024 * 1024;
if(dfsize < S3fsCurl::GetMultipartSize()){
S3FS_PRN_WARN("specified size to ensure disk free space is smaller than multipart size, so set multipart size to it.");
dfsize = S3fsCurl::GetMultipartSize();
@ -4910,7 +4910,7 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
if(0 == STR2NCMP(arg, "singlepart_copy_limit=")){
singlepart_copy_limit = static_cast<int64_t>(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))) * 1024;
singlepart_copy_limit = static_cast<int64_t>(cvt_strtoofft(strchr(arg, '=') + sizeof(char))) * 1024;
return 0;
}
if(0 == STR2NCMP(arg, "ahbe_conf=")){

View File

@ -794,7 +794,7 @@ time_t get_mtime(const char *str)
strmtime = strmtime.substr(0, pos);
}
}
return static_cast<time_t>(s3fs_strtoofft(strmtime.c_str()));
return static_cast<time_t>(cvt_strtoofft(strmtime.c_str()));
}
static time_t get_time(headers_t& meta, bool overcheck, const char *header)
@ -821,7 +821,7 @@ time_t get_ctime(headers_t& meta, bool overcheck)
off_t get_size(const char *s)
{
return s3fs_strtoofft(s);
return cvt_strtoofft(s);
}
off_t get_size(headers_t& meta)
@ -835,7 +835,7 @@ off_t get_size(headers_t& meta)
mode_t get_mode(const char *s)
{
return static_cast<mode_t>(s3fs_strtoofft(s));
return static_cast<mode_t>(cvt_strtoofft(s));
}
mode_t get_mode(headers_t& meta, const char* path, bool checkdir, bool forcedir)
@ -917,7 +917,7 @@ mode_t get_mode(headers_t& meta, const char* path, bool checkdir, bool forcedir)
uid_t get_uid(const char *s)
{
return static_cast<uid_t>(s3fs_strtoofft(s));
return static_cast<uid_t>(cvt_strtoofft(s));
}
uid_t get_uid(headers_t& meta)
@ -934,7 +934,7 @@ uid_t get_uid(headers_t& meta)
gid_t get_gid(const char *s)
{
return static_cast<gid_t>(s3fs_strtoofft(s));
return static_cast<gid_t>(cvt_strtoofft(s));
}
gid_t get_gid(headers_t& meta)

View File

@ -68,6 +68,41 @@ off_t s3fs_strtoofft(const char* str, int base)
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 string(%s) to off_t.", str);
return false;
}
}else{
S3FS_PRN_WARN("parameter string is null.");
return false;
}
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)){
S3FS_PRN_WARN("something error is occurred in convert string(%s) to off_t, thus return 0 as default.", (str ? str : "null"));
return 0;
}
return result;
}
string lower(string s)
{
// change each character of the string to lower case

View File

@ -37,6 +37,8 @@ template <class T> std::string str(T value);
// Convert string to off_t. Throws std::invalid_argument and std::out_of_range on bad input.
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);
std::string trim_left(const std::string &s, const std::string &t = SPACES);
std::string trim_right(const std::string &s, const std::string &t = SPACES);

View File

@ -20,11 +20,21 @@
#include <limits>
#include <stdint.h>
#include <strings.h>
#include <string>
#include <map>
#include "common.h"
#include "string_util.h"
#include "test_util.h"
//-------------------------------------------------------------------
// Global variables for test_string_util
//-------------------------------------------------------------------
bool foreground = false;
s3fs_log_level debug_level = S3FS_LOG_CRIT;
std::string instance_name;
void test_trim()
{
ASSERT_EQUALS(std::string("1234"), trim(" 1234 "));