diff --git a/src/curl.cpp b/src/curl.cpp index d1d57d8..f3cbb7e 100644 --- a/src/curl.cpp +++ b/src/curl.cpp @@ -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(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(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(tmp_expire); }else{ S3fsCurl::AWSAccessKeyId = keyval[string(IAMCRED_ACCESSKEYID)]; S3fsCurl::AWSSecretAccessKey = keyval[string(IAMCRED_SECRETACCESSKEY)]; diff --git a/src/fdcache.cpp b/src/fdcache.cpp index c9ce06a..7ee80ea 100644 --- a/src/fdcache.cpp +++ b/src/fdcache.cpp @@ -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 "\n" - total = wrap_strtoofft(strhead1.c_str()); + total = cvt_strtoofft(strhead1.c_str(), /* base= */10); cache_inode = 0; }else{ // current head format is ":\n" - total = wrap_strtoofft(strhead1.c_str()); - cache_inode = static_cast(wrap_strtoofft(strhead2.c_str())); + total = cvt_strtoofft(strhead1.c_str(), /* base= */10); + cache_inode = static_cast(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 = diff --git a/src/s3fs.cpp b/src/s3fs.cpp index 0a0eee6..a4cedd1 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -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(s3fs_strtoofft(strchr(arg, '=') + sizeof(char)))); + S3fsCurl::SetRetries(static_cast(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(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))); + int maxreq = static_cast(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(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))); + long sslvh = static_cast(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(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))); + long contimeout = static_cast(cvt_strtoofft(strchr(arg, '=') + sizeof(char))); S3fsCurl::SetConnectTimeout(contimeout); return 0; } if(0 == STR2NCMP(arg, "readwrite_timeout=")){ - time_t rwtimeout = static_cast(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))); + time_t rwtimeout = static_cast(cvt_strtoofft(strchr(arg, '=') + sizeof(char))); S3fsCurl::SetReadwriteTimeout(rwtimeout); return 0; } if(0 == STR2NCMP(arg, "list_object_max_keys=")){ - int max_keys = static_cast(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))); + int max_keys = static_cast(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(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))); + unsigned long cache_size = static_cast(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(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))); + time_t expr_time = static_cast(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(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))); + time_t expr_time = static_cast(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(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))); + int maxpara = static_cast(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(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))); + off_t size = static_cast(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(s3fs_strtoofft(strchr(arg, '=') + sizeof(char))) * 1024; + singlepart_copy_limit = static_cast(cvt_strtoofft(strchr(arg, '=') + sizeof(char))) * 1024; return 0; } if(0 == STR2NCMP(arg, "ahbe_conf=")){ diff --git a/src/s3fs_util.cpp b/src/s3fs_util.cpp index 4f936e1..06b5218 100644 --- a/src/s3fs_util.cpp +++ b/src/s3fs_util.cpp @@ -794,7 +794,7 @@ time_t get_mtime(const char *str) strmtime = strmtime.substr(0, pos); } } - return static_cast(s3fs_strtoofft(strmtime.c_str())); + return static_cast(cvt_strtoofft(strmtime.c_str())); } static time_t get_time(headers_t& meta, const char *header) @@ -836,7 +836,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) @@ -850,7 +850,7 @@ off_t get_size(headers_t& meta) mode_t get_mode(const char *s, int base) { - return static_cast(s3fs_strtoofft(s, base)); + return static_cast(cvt_strtoofft(s, base)); } mode_t get_mode(headers_t& meta, const char* path, bool checkdir, bool forcedir) @@ -934,7 +934,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(s3fs_strtoofft(s)); + return static_cast(cvt_strtoofft(s)); } uid_t get_uid(headers_t& meta) @@ -953,7 +953,7 @@ uid_t get_uid(headers_t& meta) gid_t get_gid(const char *s) { - return static_cast(s3fs_strtoofft(s)); + return static_cast(cvt_strtoofft(s)); } gid_t get_gid(headers_t& meta) diff --git a/src/string_util.cpp b/src/string_util.cpp index 9680466..6251d6c 100644 --- a/src/string_util.cpp +++ b/src/string_util.cpp @@ -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 diff --git a/src/string_util.h b/src/string_util.h index 82634e5..3562eb6 100644 --- a/src/string_util.h +++ b/src/string_util.h @@ -37,6 +37,8 @@ template 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); diff --git a/src/test_string_util.cpp b/src/test_string_util.cpp index f170c71..6e619ff 100644 --- a/src/test_string_util.cpp +++ b/src/test_string_util.cpp @@ -20,11 +20,21 @@ #include #include +#include #include +#include +#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 "));