mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-12-23 09:18:55 +00:00
Implement s3fs_strtoofft via strtoll
This tightens error checking and aligns s3fs with known good behavior.
This commit is contained in:
parent
e936854493
commit
4adcd4a6c8
@ -17,6 +17,7 @@
|
|||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
#include <cerrno>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -24,6 +25,7 @@
|
|||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -50,45 +52,18 @@ template std::string str(unsigned long long value);
|
|||||||
|
|
||||||
static const char hexAlphabet[] = "0123456789ABCDEF";
|
static const char hexAlphabet[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
// replacement for C++11 std::stoll
|
||||||
off_t s3fs_strtoofft(const char* str, bool is_base_16)
|
off_t s3fs_strtoofft(const char* str, bool is_base_16)
|
||||||
{
|
{
|
||||||
if(!str || '\0' == *str){
|
errno = 0;
|
||||||
return 0;
|
char *temp;
|
||||||
|
long long result = strtoll(str, &temp, is_base_16 ? 16 : 10);
|
||||||
|
|
||||||
|
if(temp == str || *temp != '\0'){
|
||||||
|
throw std::invalid_argument("s3fs_strtoofft");
|
||||||
}
|
}
|
||||||
off_t result;
|
if((result == LLONG_MIN || result == LLONG_MAX) && errno == ERANGE){
|
||||||
bool chk_space;
|
throw std::out_of_range("s3fs_strtoofft");
|
||||||
bool chk_base16_prefix;
|
|
||||||
for(result = 0, chk_space = false, chk_base16_prefix = false; '\0' != *str; str++){
|
|
||||||
// check head space
|
|
||||||
if(!chk_space && isspace(*str)){
|
|
||||||
continue;
|
|
||||||
}else if(!chk_space){
|
|
||||||
chk_space = true;
|
|
||||||
}
|
|
||||||
// check prefix for base 16
|
|
||||||
if(!chk_base16_prefix){
|
|
||||||
chk_base16_prefix = true;
|
|
||||||
if('0' == *str && ('x' == str[1] || 'X' == str[1])){
|
|
||||||
is_base_16 = true;
|
|
||||||
str++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check like isalnum and set data
|
|
||||||
result *= (is_base_16 ? 16 : 10);
|
|
||||||
if('0' <= *str && '9' >= *str){
|
|
||||||
result += static_cast<off_t>(*str - '0');
|
|
||||||
}else if(is_base_16){
|
|
||||||
if('A' <= *str && *str <= 'F'){
|
|
||||||
result += static_cast<off_t>(*str - 'A' + 0x0a);
|
|
||||||
}else if('a' <= *str && *str <= 'f'){
|
|
||||||
result += static_cast<off_t>(*str - 'a' + 0x0a);
|
|
||||||
}else{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ static inline int STR2NCMP(const char *str1, const char *str2) { return strncmp(
|
|||||||
|
|
||||||
template <class T> std::string str(T value);
|
template <class T> std::string str(T value);
|
||||||
|
|
||||||
// Convert string to off_t. Does not signal invalid input.
|
// Convert string to off_t. Throws std::invalid_argument and std::out_of_range on bad input.
|
||||||
off_t s3fs_strtoofft(const char* str, bool is_base_16 = false);
|
off_t s3fs_strtoofft(const char* str, bool is_base_16 = false);
|
||||||
|
|
||||||
std::string trim_left(const std::string &s, const std::string &t = SPACES);
|
std::string trim_left(const std::string &s, const std::string &t = SPACES);
|
||||||
|
@ -79,7 +79,12 @@ void test_strtoofft()
|
|||||||
{
|
{
|
||||||
ASSERT_EQUALS(s3fs_strtoofft("0"), static_cast<off_t>(0L));
|
ASSERT_EQUALS(s3fs_strtoofft("0"), static_cast<off_t>(0L));
|
||||||
ASSERT_EQUALS(s3fs_strtoofft("9"), static_cast<off_t>(9L));
|
ASSERT_EQUALS(s3fs_strtoofft("9"), static_cast<off_t>(9L));
|
||||||
ASSERT_EQUALS(s3fs_strtoofft("A"), static_cast<off_t>(0L));
|
try{
|
||||||
|
s3fs_strtoofft("A");
|
||||||
|
abort();
|
||||||
|
}catch(std::exception &e){
|
||||||
|
// expected
|
||||||
|
}
|
||||||
ASSERT_EQUALS(s3fs_strtoofft("A", /*is_base_16=*/ true), static_cast<off_t>(10L));
|
ASSERT_EQUALS(s3fs_strtoofft("A", /*is_base_16=*/ true), static_cast<off_t>(10L));
|
||||||
ASSERT_EQUALS(s3fs_strtoofft("F", /*is_base_16=*/ true), static_cast<off_t>(15L));
|
ASSERT_EQUALS(s3fs_strtoofft("F", /*is_base_16=*/ true), static_cast<off_t>(15L));
|
||||||
ASSERT_EQUALS(s3fs_strtoofft("a", /*is_base_16=*/ true), static_cast<off_t>(10L));
|
ASSERT_EQUALS(s3fs_strtoofft("a", /*is_base_16=*/ true), static_cast<off_t>(10L));
|
||||||
|
Loading…
Reference in New Issue
Block a user