Commit 4f174825 authored by Allen Bauer's avatar Allen Bauer Committed by Commit Bot

Made type conversions from string more resilient by providing a default value.

Bug: 960779
Change-Id: I21dedf74f9930732cb130ece2bfeee737aba6dc5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1603062
Commit-Queue: Allen Bauer <kylixrd@chromium.org>
Auto-Submit: Allen Bauer <kylixrd@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#658316}
parent f9d8f7f6
...@@ -185,8 +185,8 @@ class ClassPropertyMetaData ...@@ -185,8 +185,8 @@ class ClassPropertyMetaData
~ClassPropertyMetaData() override = default; ~ClassPropertyMetaData() override = default;
void SetValueAsString(void* obj, const base::string16& new_value) override { void SetValueAsString(void* obj, const base::string16& new_value) override {
(static_cast<TClass*>(obj)->*Set)( (static_cast<TClass*>(obj)->*Set)(Convert<base::string16, TValue>(
Convert<base::string16, TValue>(new_value)); new_value, (static_cast<TClass*>(obj)->*Get)()));
} }
PropertyFlags GetPropertyFlags() const override { PropertyFlags GetPropertyFlags() const override {
......
...@@ -84,81 +84,97 @@ base::string16 ConvertToString<gfx::Size>(const gfx::Size& source_value) { ...@@ -84,81 +84,97 @@ base::string16 ConvertToString<gfx::Size>(const gfx::Size& source_value) {
} }
template <> template <>
int8_t ConvertFromString<int8_t>(const base::string16& source_value) { int8_t ConvertFromString<int8_t>(const base::string16& source_value,
int8_t default_value) {
int32_t ret = 0; int32_t ret = 0;
return base::StringToInt(source_value, &ret) && return base::StringToInt(source_value, &ret) &&
base::IsValueInRangeForNumericType<int8_t>(ret) base::IsValueInRangeForNumericType<int8_t>(ret)
? static_cast<int8_t>(ret) ? static_cast<int8_t>(ret)
: 0; : default_value;
} }
template <> template <>
int16_t ConvertFromString<int16_t>(const base::string16& source_value) { int16_t ConvertFromString<int16_t>(const base::string16& source_value,
int16_t default_value) {
int32_t ret = 0; int32_t ret = 0;
return base::StringToInt(source_value, &ret) && return base::StringToInt(source_value, &ret) &&
base::IsValueInRangeForNumericType<int16_t>(ret) base::IsValueInRangeForNumericType<int16_t>(ret)
? static_cast<int16_t>(ret) ? static_cast<int16_t>(ret)
: 0; : default_value;
} }
template <> template <>
int32_t ConvertFromString<int32_t>(const base::string16& source_value) { int32_t ConvertFromString<int32_t>(const base::string16& source_value,
int32_t default_value) {
int32_t ret = 0; int32_t ret = 0;
return base::StringToInt(source_value, &ret) ? static_cast<int32_t>(ret) : 0; return base::StringToInt(source_value, &ret) ? static_cast<int32_t>(ret)
: default_value;
} }
template <> template <>
int64_t ConvertFromString<int64_t>(const base::string16& source_value) { int64_t ConvertFromString<int64_t>(const base::string16& source_value,
int64_t default_value) {
int64_t ret = 0; int64_t ret = 0;
return base::StringToInt64(source_value, &ret) ? ret : 0; return base::StringToInt64(source_value, &ret) ? ret : default_value;
} }
template <> template <>
uint8_t ConvertFromString<uint8_t>(const base::string16& source_value) { uint8_t ConvertFromString<uint8_t>(const base::string16& source_value,
uint8_t default_value) {
uint32_t ret = 0; uint32_t ret = 0;
return base::StringToUint(source_value, &ret) && return base::StringToUint(source_value, &ret) &&
base::IsValueInRangeForNumericType<uint8_t>(ret) base::IsValueInRangeForNumericType<uint8_t>(ret)
? static_cast<uint8_t>(ret) ? static_cast<uint8_t>(ret)
: 0; : default_value;
} }
template <> template <>
uint16_t ConvertFromString<uint16_t>(const base::string16& source_value) { uint16_t ConvertFromString<uint16_t>(const base::string16& source_value,
uint16_t default_value) {
uint32_t ret = 0; uint32_t ret = 0;
return base::StringToUint(source_value, &ret) && return base::StringToUint(source_value, &ret) &&
base::IsValueInRangeForNumericType<uint16_t>(ret) base::IsValueInRangeForNumericType<uint16_t>(ret)
? static_cast<uint16_t>(ret) ? static_cast<uint16_t>(ret)
: 0; : default_value;
} }
template <> template <>
uint32_t ConvertFromString<uint32_t>(const base::string16& source_value) { uint32_t ConvertFromString<uint32_t>(const base::string16& source_value,
uint32_t default_value) {
uint32_t ret = 0; uint32_t ret = 0;
return base::StringToUint(source_value, &ret) ? static_cast<uint32_t>(ret) return base::StringToUint(source_value, &ret) ? static_cast<uint32_t>(ret)
: 0; : default_value;
} }
template <> template <>
uint64_t ConvertFromString<uint64_t>(const base::string16& source_value) { uint64_t ConvertFromString<uint64_t>(const base::string16& source_value,
uint64_t default_value) {
uint64_t ret = 0; uint64_t ret = 0;
return base::StringToUint64(source_value, &ret) ? ret : 0; return base::StringToUint64(source_value, &ret) ? ret : default_value;
} }
template <> template <>
float ConvertFromString<float>(const base::string16& source_value) { float ConvertFromString<float>(const base::string16& source_value,
return static_cast<float>(ConvertFromString<double>(source_value)); float default_value) {
return static_cast<float>(
ConvertFromString<double>(source_value, default_value));
} }
template <> template <>
double ConvertFromString<double>(const base::string16& source_value) { double ConvertFromString<double>(const base::string16& source_value,
double default_value) {
double ret = 0; double ret = 0;
return base::StringToDouble(base::UTF16ToUTF8(source_value), &ret) ? ret return base::StringToDouble(base::UTF16ToUTF8(source_value), &ret)
: 0.0; ? ret
: default_value;
} }
template <> template <>
bool ConvertFromString<bool>(const base::string16& source_value) { bool ConvertFromString<bool>(const base::string16& source_value,
return source_value == base::ASCIIToUTF16("true"); bool default_value) {
if (source_value == base::ASCIIToUTF16("false"))
return false;
return source_value == base::ASCIIToUTF16("true") || default_value;
} }
} // namespace metadata } // namespace metadata
......
...@@ -33,17 +33,23 @@ template <typename TSource, typename TTarget> ...@@ -33,17 +33,23 @@ template <typename TSource, typename TTarget>
class TypeConverter { class TypeConverter {
public: public:
static TTarget Convert(ArgType<TSource>) = delete; static TTarget Convert(ArgType<TSource>) = delete;
static TTarget Convert(ArgType<TSource>, ArgType<TTarget>) = delete;
private: private:
TypeConverter(); TypeConverter();
}; };
// Master Type Conversion Function -------------------------------------------- // Master Type Conversion Functions --------------------------------------------
template <typename TSource, typename TTarget> template <typename TSource, typename TTarget>
TTarget Convert(ArgType<TSource> source_value) { TTarget Convert(ArgType<TSource> source_value) {
return TypeConverter<TSource, TTarget>::Convert(source_value); return TypeConverter<TSource, TTarget>::Convert(source_value);
} }
template <typename TSource, typename TTarget>
TTarget Convert(ArgType<TSource> source_value, ArgType<TTarget> default_value) {
return TypeConverter<TSource, TTarget>::Convert(source_value, default_value);
}
// String Conversions --------------------------------------------------------- // String Conversions ---------------------------------------------------------
template <typename TSource> template <typename TSource>
...@@ -106,58 +112,74 @@ class TypeConverter<base::string16, base::string16> { ...@@ -106,58 +112,74 @@ class TypeConverter<base::string16, base::string16> {
static base::string16 Convert(const base::string16& source_val) { static base::string16 Convert(const base::string16& source_val) {
return ConvertToString<base::string16>(source_val); return ConvertToString<base::string16>(source_val);
} }
static base::string16 Convert(const base::string16& source_val,
const base::string16& default_value) {
return ConvertToString<base::string16>(source_val);
}
}; };
template <typename TTarget> template <typename TTarget>
TTarget ConvertFromString(const base::string16& source_value) = delete; TTarget ConvertFromString(const base::string16&, ArgType<TTarget>) = delete;
template <> template <>
VIEWS_EXPORT int8_t VIEWS_EXPORT int8_t
ConvertFromString<int8_t>(const base::string16& source_value); ConvertFromString<int8_t>(const base::string16& source_value,
int8_t default_value);
template <> template <>
VIEWS_EXPORT int16_t VIEWS_EXPORT int16_t
ConvertFromString<int16_t>(const base::string16& source_value); ConvertFromString<int16_t>(const base::string16& source_value,
int16_t default_value);
template <> template <>
VIEWS_EXPORT int32_t VIEWS_EXPORT int32_t
ConvertFromString<int32_t>(const base::string16& source_value); ConvertFromString<int32_t>(const base::string16& source_value,
int32_t default_value);
template <> template <>
VIEWS_EXPORT int64_t VIEWS_EXPORT int64_t
ConvertFromString<int64_t>(const base::string16& source_value); ConvertFromString<int64_t>(const base::string16& source_value,
int64_t default_value);
template <> template <>
VIEWS_EXPORT uint8_t VIEWS_EXPORT uint8_t
ConvertFromString<uint8_t>(const base::string16& source_value); ConvertFromString<uint8_t>(const base::string16& source_value,
uint8_t default_value);
template <> template <>
VIEWS_EXPORT uint16_t VIEWS_EXPORT uint16_t
ConvertFromString<uint16_t>(const base::string16& source_value); ConvertFromString<uint16_t>(const base::string16& source_value,
uint16_t default_value);
template <> template <>
VIEWS_EXPORT uint32_t VIEWS_EXPORT uint32_t
ConvertFromString<uint32_t>(const base::string16& source_value); ConvertFromString<uint32_t>(const base::string16& source_value,
uint32_t default_value);
template <> template <>
VIEWS_EXPORT uint64_t VIEWS_EXPORT uint64_t
ConvertFromString<uint64_t>(const base::string16& source_value); ConvertFromString<uint64_t>(const base::string16& source_value,
uint64_t default_value);
template <> template <>
VIEWS_EXPORT double ConvertFromString<double>( VIEWS_EXPORT double ConvertFromString<double>(
const base::string16& source_value); const base::string16& source_value,
double default_value);
template <> template <>
VIEWS_EXPORT float ConvertFromString<float>(const base::string16& source_value); VIEWS_EXPORT float ConvertFromString<float>(const base::string16& source_value,
float default_value);
template <> template <>
VIEWS_EXPORT bool ConvertFromString<bool>(const base::string16& source_value); VIEWS_EXPORT bool ConvertFromString<bool>(const base::string16& source_value,
bool default_value);
template <typename TTarget> template <typename TTarget>
class TypeConverter<base::string16, TTarget> { class TypeConverter<base::string16, TTarget> {
public: public:
static TTarget Convert(const base::string16& source_value) { static TTarget Convert(const base::string16& source_value,
return ConvertFromString<TTarget>(source_value); ArgType<TTarget> default_value) {
return ConvertFromString<TTarget>(source_value, default_value);
} }
}; };
......
...@@ -9,20 +9,30 @@ ...@@ -9,20 +9,30 @@
#include "testing/platform_test.h" #include "testing/platform_test.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
namespace TC = views::metadata; namespace VM = views::metadata;
using TypeConversionTest = PlatformTest; using TypeConversionTest = PlatformTest;
TEST_F(TypeConversionTest, TestConversion_IntToString) { TEST_F(TypeConversionTest, TestConversion_IntToString) {
int from_int = 5; int from_int = 5;
base::string16 to_string = TC::Convert<int, base::string16>(from_int); base::string16 to_string = VM::Convert<int, base::string16>(from_int);
EXPECT_EQ(to_string, base::ASCIIToUTF16("5")); EXPECT_EQ(to_string, base::ASCIIToUTF16("5"));
} }
TEST_F(TypeConversionTest, TestConversion_StringToInt) { TEST_F(TypeConversionTest, TestConversion_StringToInt) {
base::string16 from_string = base::ASCIIToUTF16("10"); base::string16 from_string = base::ASCIIToUTF16("10");
int to_int = TC::Convert<base::string16, int>(from_string); int to_int = VM::Convert<base::string16, int>(from_string, 0);
EXPECT_EQ(to_int, 10); EXPECT_EQ(to_int, 10);
} }
// This tests whether the converter handles a bogus input string, in which case
// the default value should be returned.
TEST_F(TypeConversionTest, TestConversion_StringToIntDefault) {
const int default_value = 1000;
base::string16 from_string = base::ASCIIToUTF16("Foo");
int to_int = VM::Convert<base::string16, int>(from_string, default_value);
EXPECT_EQ(to_int, default_value);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment