diff options
| author | Tom Cherry <tomcherry@google.com> | 2018-08-22 14:38:02 -0700 |
|---|---|---|
| committer | Tom Cherry <tomcherry@google.com> | 2018-08-22 15:02:57 -0700 |
| commit | 8e3f0b1b2a0866ef1d5c1ae7f832617ca87f6d84 (patch) | |
| tree | b49ac91e1ad7e471a0c44ee15c05f7bc82146cbe /base | |
| parent | 22c1eefb0df8ca42659b8869498622039695e2a2 (diff) | |
| download | system_core-8e3f0b1b2a0866ef1d5c1ae7f832617ca87f6d84.tar.gz system_core-8e3f0b1b2a0866ef1d5c1ae7f832617ca87f6d84.tar.bz2 system_core-8e3f0b1b2a0866ef1d5c1ae7f832617ca87f6d84.zip | |
Fix two ParseInt edge cases
1) ParseInt and ParseUint accept strings that have spaces followed by
a valid number, however the base check for determining hex numbers
does not take this into account currently, but now does this this
change.
2) ParseUint rejects negative numbers except in the case that the
template argument is unsigned long long. That is a mistake; it
should reject negative numbers in all cases and this change does
that by rejecting any string with a - prefix.
Bug: 112668205
Test: new (and old) unit tests
Change-Id: I0179b42e50adc1b169cf0e6d830283b71210a029
Diffstat (limited to 'base')
| -rw-r--r-- | base/include/android-base/parseint.h | 12 | ||||
| -rw-r--r-- | base/parseint_test.cpp | 20 |
2 files changed, 32 insertions, 0 deletions
diff --git a/base/include/android-base/parseint.h b/base/include/android-base/parseint.h index 55f1ed3ea..5bfa47e8e 100644 --- a/base/include/android-base/parseint.h +++ b/base/include/android-base/parseint.h @@ -33,6 +33,14 @@ namespace base { template <typename T> bool ParseUint(const char* s, T* out, T max = std::numeric_limits<T>::max(), bool allow_suffixes = false) { + while (isspace(*s)) { + s++; + } + + if (s[0] == '-') { + return false; + } + int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10; errno = 0; char* end; @@ -79,6 +87,10 @@ template <typename T> bool ParseInt(const char* s, T* out, T min = std::numeric_limits<T>::min(), T max = std::numeric_limits<T>::max()) { + while (isspace(*s)) { + s++; + } + int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10; errno = 0; char* end; diff --git a/base/parseint_test.cpp b/base/parseint_test.cpp index 8f9ed776b..4afa32e3e 100644 --- a/base/parseint_test.cpp +++ b/base/parseint_test.cpp @@ -25,8 +25,14 @@ TEST(parseint, signed_smoke) { ASSERT_TRUE(android::base::ParseInt("123", &i)); ASSERT_EQ(123, i); + i = 0; + EXPECT_TRUE(android::base::ParseInt(" 123", &i)); + EXPECT_EQ(123, i); ASSERT_TRUE(android::base::ParseInt("-123", &i)); ASSERT_EQ(-123, i); + i = 0; + EXPECT_TRUE(android::base::ParseInt(" -123", &i)); + EXPECT_EQ(-123, i); short s = 0; ASSERT_TRUE(android::base::ParseInt("1234", &s)); @@ -49,7 +55,11 @@ TEST(parseint, unsigned_smoke) { ASSERT_TRUE(android::base::ParseUint("123", &i)); ASSERT_EQ(123u, i); + i = 0u; + EXPECT_TRUE(android::base::ParseUint(" 123", &i)); + EXPECT_EQ(123u, i); ASSERT_FALSE(android::base::ParseUint("-123", &i)); + EXPECT_FALSE(android::base::ParseUint(" -123", &i)); unsigned short s = 0u; ASSERT_TRUE(android::base::ParseUint("1234", &s)); @@ -63,6 +73,10 @@ TEST(parseint, unsigned_smoke) { ASSERT_FALSE(android::base::ParseUint<unsigned short>("x", nullptr)); ASSERT_FALSE(android::base::ParseUint<unsigned short>("123x", nullptr)); ASSERT_TRUE(android::base::ParseUint<unsigned short>("1234", nullptr)); + + unsigned long long int lli; + EXPECT_FALSE(android::base::ParseUint("-123", &lli)); + EXPECT_FALSE(android::base::ParseUint(" -123", &lli)); } TEST(parseint, no_implicit_octal) { @@ -79,10 +93,16 @@ TEST(parseint, explicit_hex) { int i = 0; ASSERT_TRUE(android::base::ParseInt("0x123", &i)); ASSERT_EQ(0x123, i); + i = 0; + EXPECT_TRUE(android::base::ParseInt(" 0x123", &i)); + EXPECT_EQ(0x123, i); unsigned int u = 0u; ASSERT_TRUE(android::base::ParseUint("0x123", &u)); ASSERT_EQ(0x123u, u); + u = 0u; + EXPECT_TRUE(android::base::ParseUint(" 0x123", &u)); + EXPECT_EQ(0x123u, u); } TEST(parseint, string) { |
