| Index: base/string_util.cc
|
| diff --git a/base/string_util.cc b/base/string_util.cc
|
| index 2f20d780e9b3fa48a958e0b7a70eaef8a1283f85..b456376ee4460d10de3ecfb45fbdbb112a504fa5 100644
|
| --- a/base/string_util.cc
|
| +++ b/base/string_util.cc
|
| @@ -94,24 +94,53 @@ bool StringToNumber(const typename StringToNumberTraits::string_type& input,
|
| traits::valid_func(input);
|
| }
|
|
|
| -class StringToLongTraits {
|
| +static int strtoi(const char *nptr, char **endptr, int base) {
|
| + long res = strtol(nptr, endptr, base);
|
| +#if __LP64__
|
| + // Long is 64-bits, we have to handle under/overflow ourselves.
|
| + if (res > kint32max) {
|
| + res = kint32max;
|
| + errno = ERANGE;
|
| + } else if (res < kint32min) {
|
| + res = kint32min;
|
| + errno = ERANGE;
|
| + }
|
| +#endif
|
| + return static_cast<int>(res);
|
| +}
|
| +
|
| +static unsigned int strtoui(const char *nptr, char **endptr, int base) {
|
| + unsigned long res = strtoul(nptr, endptr, base);
|
| +#if __LP64__
|
| + // Long is 64-bits, we have to handle under/overflow ourselves. Test to see
|
| + // if the result can fit into 32-bits (as signed or unsigned).
|
| + if (static_cast<int>(static_cast<long>(res)) != static_cast<long>(res) &&
|
| + static_cast<unsigned int>(res) != res) {
|
| + res = kuint32max;
|
| + errno = ERANGE;
|
| + }
|
| +#endif
|
| + return static_cast<unsigned int>(res);
|
| +}
|
| +
|
| +class StringToIntTraits {
|
| public:
|
| typedef std::string string_type;
|
| - typedef long value_type;
|
| + typedef int value_type;
|
| static const int kBase = 10;
|
| static inline value_type convert_func(const string_type::value_type* str,
|
| string_type::value_type** endptr) {
|
| - return strtol(str, endptr, kBase);
|
| + return strtoi(str, endptr, kBase);
|
| }
|
| static inline bool valid_func(const string_type& str) {
|
| return !str.empty() && !isspace(str[0]);
|
| }
|
| };
|
|
|
| -class String16ToLongTraits {
|
| +class String16ToIntTraits {
|
| public:
|
| typedef string16 string_type;
|
| - typedef long value_type;
|
| + typedef int value_type;
|
| static const int kBase = 10;
|
| static inline value_type convert_func(const string_type::value_type* str,
|
| string_type::value_type** endptr) {
|
| @@ -120,7 +149,7 @@ class String16ToLongTraits {
|
| #elif defined(WCHAR_T_IS_UTF32)
|
| std::string ascii_string = UTF16ToASCII(string16(str));
|
| char* ascii_end = NULL;
|
| - value_type ret = strtol(ascii_string.c_str(), &ascii_end, kBase);
|
| + value_type ret = strtoi(ascii_string.c_str(), &ascii_end, kBase);
|
| if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
|
| *endptr =
|
| const_cast<string_type::value_type*>(str) + ascii_string.length();
|
| @@ -179,24 +208,24 @@ class String16ToInt64Traits {
|
| // For the HexString variants, use the unsigned variants like strtoul for
|
| // convert_func so that input like "0x80000000" doesn't result in an overflow.
|
|
|
| -class HexStringToLongTraits {
|
| +class HexStringToIntTraits {
|
| public:
|
| typedef std::string string_type;
|
| - typedef long value_type;
|
| + typedef int value_type;
|
| static const int kBase = 16;
|
| static inline value_type convert_func(const string_type::value_type* str,
|
| string_type::value_type** endptr) {
|
| - return strtoul(str, endptr, kBase);
|
| + return strtoui(str, endptr, kBase);
|
| }
|
| static inline bool valid_func(const string_type& str) {
|
| return !str.empty() && !isspace(str[0]);
|
| }
|
| };
|
|
|
| -class HexString16ToLongTraits {
|
| +class HexString16ToIntTraits {
|
| public:
|
| typedef string16 string_type;
|
| - typedef long value_type;
|
| + typedef int value_type;
|
| static const int kBase = 16;
|
| static inline value_type convert_func(const string_type::value_type* str,
|
| string_type::value_type** endptr) {
|
| @@ -205,7 +234,7 @@ class HexString16ToLongTraits {
|
| #elif defined(WCHAR_T_IS_UTF32)
|
| std::string ascii_string = UTF16ToASCII(string16(str));
|
| char* ascii_end = NULL;
|
| - value_type ret = strtoul(ascii_string.c_str(), &ascii_end, kBase);
|
| + value_type ret = strtoui(ascii_string.c_str(), &ascii_end, kBase);
|
| if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
|
| *endptr =
|
| const_cast<string_type::value_type*>(str) + ascii_string.length();
|
| @@ -1440,21 +1469,12 @@ bool MatchPattern(const std::string& eval, const std::string& pattern) {
|
| return MatchPatternT(eval.c_str(), pattern.c_str());
|
| }
|
|
|
| -// For the various *ToInt conversions, there are no *ToIntTraits classes to use
|
| -// because there's no such thing as strtoi. Use *ToLongTraits through a cast
|
| -// instead, requiring that long and int are compatible and equal-width. They
|
| -// are on our target platforms.
|
| -
|
| bool StringToInt(const std::string& input, int* output) {
|
| - COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
|
| - return StringToNumber<StringToLongTraits>(input,
|
| - reinterpret_cast<long*>(output));
|
| + return StringToNumber<StringToIntTraits>(input, output);
|
| }
|
|
|
| bool StringToInt(const string16& input, int* output) {
|
| - COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
|
| - return StringToNumber<String16ToLongTraits>(input,
|
| - reinterpret_cast<long*>(output));
|
| + return StringToNumber<String16ToIntTraits>(input, output);
|
| }
|
|
|
| bool StringToInt64(const std::string& input, int64* output) {
|
| @@ -1466,15 +1486,11 @@ bool StringToInt64(const string16& input, int64* output) {
|
| }
|
|
|
| bool HexStringToInt(const std::string& input, int* output) {
|
| - COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
|
| - return StringToNumber<HexStringToLongTraits>(input,
|
| - reinterpret_cast<long*>(output));
|
| + return StringToNumber<HexStringToIntTraits>(input, output);
|
| }
|
|
|
| bool HexStringToInt(const string16& input, int* output) {
|
| - COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
|
| - return StringToNumber<HexString16ToLongTraits>(
|
| - input, reinterpret_cast<long*>(output));
|
| + return StringToNumber<HexString16ToIntTraits>(input, output);
|
| }
|
|
|
| namespace {
|
|
|