diff options
author | Lei Zhang <thestig@chromium.org> | 2015-08-18 13:17:51 -0700 |
---|---|---|
committer | Lei Zhang <thestig@chromium.org> | 2015-08-18 13:17:51 -0700 |
commit | f81f724838983add18125f41292e98ef94e1bb39 (patch) | |
tree | 81b54edf1aae0cab9a029ff94de300a83a65c8f9 | |
parent | 3519320afaaaf373c17f9ec7d74117af3c7ab0ec (diff) | |
download | pdfium-f81f724838983add18125f41292e98ef94e1bb39.tar.xz |
Merge to M45: Fix FXSYS_itoa() implementation.
I thought about removing it, but decided to fix it instead until c++11
hits and there may be better alternatives.
Remove unused variants.
R=tsepez@chromium.org
TBR=tsepez@chromium.org
BUG=517854
Review URL: https://codereview.chromium.org/1274423003 .
(cherry picked from commit 9778206732296e949ef22a79362c6bce34a56052)
Review URL: https://codereview.chromium.org/1291873004 .
-rw-r--r-- | BUILD.gn | 1 | ||||
-rw-r--r-- | core/include/fxcrt/fx_system.h | 1 | ||||
-rw-r--r-- | core/src/fxcrt/fx_basic_gcc.cpp | 39 | ||||
-rw-r--r-- | core/src/fxcrt/fx_system_unittest.cpp | 164 | ||||
-rw-r--r-- | pdfium.gyp | 1 |
5 files changed, 189 insertions, 17 deletions
@@ -731,6 +731,7 @@ test("pdfium_unittests") { "core/src/fxcrt/fx_basic_bstring_unittest.cpp", "core/src/fxcrt/fx_basic_memmgr_unittest.cpp", "core/src/fxcrt/fx_basic_wstring_unittest.cpp", + "core/src/fxcrt/fx_system_unittest.cpp", "testing/fx_string_testhelpers.cpp", "testing/fx_string_testhelpers.h", ] diff --git a/core/include/fxcrt/fx_system.h b/core/include/fxcrt/fx_system.h index 8bc2b4ab2a..87da585b00 100644 --- a/core/include/fxcrt/fx_system.h +++ b/core/include/fxcrt/fx_system.h @@ -244,7 +244,6 @@ int32_t FXSYS_wtoi(const FX_WCHAR* str); int64_t FXSYS_atoi64(const FX_CHAR* str); int64_t FXSYS_wtoi64(const FX_WCHAR* str); const FX_CHAR* FXSYS_i64toa(int64_t value, FX_CHAR* str, int radix); -const FX_WCHAR* FXSYS_i64tow(int64_t value, FX_WCHAR* str, int radix); int FXSYS_round(FX_FLOAT f); #define FXSYS_Mul(a, b) ((a) * (b)) #define FXSYS_Div(a, b) ((a) / (b)) diff --git a/core/src/fxcrt/fx_basic_gcc.cpp b/core/src/fxcrt/fx_basic_gcc.cpp index e4416e95b5..fb9db59b53 100644 --- a/core/src/fxcrt/fx_basic_gcc.cpp +++ b/core/src/fxcrt/fx_basic_gcc.cpp @@ -33,31 +33,42 @@ T FXSYS_StrToInt(STR_T str) } return neg ? -num : num; } -template <typename T, typename STR_T> + +template <typename T, typename UT, typename STR_T> STR_T FXSYS_IntToStr(T value, STR_T string, int radix) { - int i = 0; - if (value < 0) { - string[i++] = '-'; - value = -value; - } else if (value == 0) { + if (radix < 2 || radix > 16) { + string[0] = 0; + return string; + } + if (value == 0) { string[0] = '0'; string[1] = 0; return string; } + int i = 0; + UT uvalue; + if (value < 0) { + string[i++] = '-'; + // Standard trick to avoid undefined behaviour when negating INT_MIN. + uvalue = static_cast<UT>(-(value + 1)) + 1; + } else { + uvalue = value; + } int digits = 1; - T order = value / 10; + T order = uvalue / radix; while(order > 0) { digits++; - order = order / 10; + order = order / radix; } for (int d = digits - 1; d > -1; d--) { - string[d + i] = "0123456789abcdef"[value % 10]; - value /= 10; + string[d + i] = "0123456789abcdef"[uvalue % radix]; + uvalue /= radix; } string[digits + i] = 0; return string; } + #ifdef __cplusplus extern "C" { #endif @@ -79,11 +90,7 @@ int64_t FXSYS_wtoi64(const FX_WCHAR* str) } const FX_CHAR* FXSYS_i64toa(int64_t value, FX_CHAR* str, int radix) { - return FXSYS_IntToStr<int64_t, FX_CHAR*>(value, str, radix); -} -const FX_WCHAR* FXSYS_i64tow(int64_t value, FX_WCHAR* str, int radix) -{ - return FXSYS_IntToStr<int64_t, FX_WCHAR*>(value, str, radix); + return FXSYS_IntToStr<int64_t, uint64_t, FX_CHAR*>(value, str, radix); } #ifdef __cplusplus } @@ -197,7 +204,7 @@ int FXSYS_wcsicmp(const FX_WCHAR *dst, const FX_WCHAR *src) } char* FXSYS_itoa(int value, char* string, int radix) { - return FXSYS_IntToStr<int32_t, FX_CHAR*>(value, string, radix); + return FXSYS_IntToStr<int32_t, uint32_t, FX_CHAR*>(value, string, radix); } #ifdef __cplusplus } diff --git a/core/src/fxcrt/fx_system_unittest.cpp b/core/src/fxcrt/fx_system_unittest.cpp new file mode 100644 index 0000000000..fec6063b0d --- /dev/null +++ b/core/src/fxcrt/fx_system_unittest.cpp @@ -0,0 +1,164 @@ +// Copyright 2015 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "testing/gtest/include/gtest/gtest.h" +#include "../../../testing/fx_string_testhelpers.h" +#include "../../include/fxcrt/fx_system.h" + +// Unit test covering cases where PDFium replaces well-known library +// functionality on any given platformn. + +#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + +namespace { + +const FX_CHAR kSentinel = 0x7f; + +void Check32BitBase16Itoa(int32_t input, const char* expected_output) { + const size_t kBufLen = 11; // "-" + 8 digits + NUL + sentinel. + FX_CHAR buf[kBufLen]; + buf[kBufLen - 1] = kSentinel; + FXSYS_itoa(input, buf, 16); + EXPECT_EQ(std::string(expected_output), buf); + EXPECT_EQ(kSentinel, buf[kBufLen - 1]); +} + +void Check32BitBase10Itoa(int32_t input, const char* expected_output) { + const size_t kBufLen = 13; // "-" + 10 digits + NUL + sentinel. + FX_CHAR buf[kBufLen]; + buf[kBufLen - 1] = kSentinel; + FXSYS_itoa(input, buf, 10); + EXPECT_EQ(std::string(expected_output), buf); + EXPECT_EQ(kSentinel, buf[kBufLen - 1]); +} + +void Check32BitBase2Itoa(int32_t input, const char* expected_output) { + const size_t kBufLen = 35; // "-" + 32 digits + NUL + sentinel. + FX_CHAR buf[kBufLen]; + buf[kBufLen - 1] = kSentinel; + FXSYS_itoa(input, buf, 2); + EXPECT_EQ(std::string(expected_output), buf); + EXPECT_EQ(kSentinel, buf[kBufLen - 1]); +} + +void Check64BitBase16Itoa(int64_t input, const char* expected_output) { + const size_t kBufLen = 19; // "-" + 16 digits + NUL + sentinel. + FX_CHAR buf[kBufLen]; + buf[kBufLen - 1] = kSentinel; + FXSYS_i64toa(input, buf, 16); + EXPECT_EQ(std::string(expected_output), buf); + EXPECT_EQ(kSentinel, buf[kBufLen - 1]); +} + +void Check64BitBase10Itoa(int64_t input, const char* expected_output) { + const size_t kBufLen = 22; // "-" + 19 digits + NUL + sentinel. + FX_CHAR buf[kBufLen]; + buf[kBufLen - 1] = kSentinel; + FXSYS_i64toa(input, buf, 10); + EXPECT_EQ(std::string(expected_output), buf); + EXPECT_EQ(kSentinel, buf[kBufLen - 1]); +} + +void Check64BitBase2Itoa(int64_t input, const char* expected_output) { + const size_t kBufLen = 67; // "-" + 64 digits + NUL + sentinel. + FX_CHAR buf[kBufLen]; + buf[kBufLen - 1] = kSentinel; + FXSYS_i64toa(input, buf, 2); + EXPECT_EQ(std::string(expected_output), buf); + EXPECT_EQ(kSentinel, buf[kBufLen - 1]); +} + +} // namespace + +TEST(fxcrt, FXSYS_itoa_InvalidRadix) { + FX_CHAR buf[32]; + + FXSYS_itoa(42, buf, 17); // Ours stops at 16. + EXPECT_EQ(std::string(""), buf); + + FXSYS_itoa(42, buf, 1); + EXPECT_EQ(std::string(""), buf); + + FXSYS_itoa(42, buf, 0); + EXPECT_EQ(std::string(""), buf); + + FXSYS_itoa(42, buf, -1); + EXPECT_EQ(std::string(""), buf); +} + +TEST(fxcrt, FXSYS_itoa) { + Check32BitBase16Itoa(std::numeric_limits<int32_t>::min(), "-80000000"); + Check32BitBase10Itoa(std::numeric_limits<int32_t>::min(), "-2147483648"); + Check32BitBase2Itoa(std::numeric_limits<int32_t>::min(), + "-10000000000000000000000000000000"); + + Check32BitBase16Itoa(-1, "-1"); + Check32BitBase10Itoa(-1, "-1"); + Check32BitBase2Itoa(-1, "-1"); + + Check32BitBase16Itoa(0, "0"); + Check32BitBase10Itoa(0, "0"); + Check32BitBase2Itoa(0, "0"); + + Check32BitBase16Itoa(42, "2a"); + Check32BitBase10Itoa(42, "42"); + Check32BitBase2Itoa(42, "101010"); + + Check32BitBase16Itoa(std::numeric_limits<int32_t>::max(), "7fffffff"); + Check32BitBase10Itoa(std::numeric_limits<int32_t>::max(), "2147483647"); + Check32BitBase2Itoa(std::numeric_limits<int32_t>::max(), + "1111111111111111111111111111111"); +} + +TEST(fxcrt, FXSYS_i64toa_InvalidRadix) { + FX_CHAR buf[32]; + + FXSYS_i64toa(42, buf, 17); // Ours stops at 16. + EXPECT_EQ(std::string(""), buf); + + FXSYS_i64toa(42, buf, 1); + EXPECT_EQ(std::string(""), buf); + + FXSYS_i64toa(42, buf, 0); + EXPECT_EQ(std::string(""), buf); + + FXSYS_i64toa(42, buf, -1); + EXPECT_EQ(std::string(""), buf); +}; + + +TEST(fxcrt, FXSYS_i64toa) { + Check64BitBase16Itoa( + std::numeric_limits<int64_t>::min(), "-8000000000000000"); + Check64BitBase10Itoa( + std::numeric_limits<int64_t>::min(), "-9223372036854775808"); + Check64BitBase2Itoa( + std::numeric_limits<int64_t>::min(), + "-1000000000000000000000000000000000000000000000000000000000000000"); + + Check64BitBase16Itoa(-1, "-1"); + Check64BitBase10Itoa(-1, "-1"); + Check64BitBase2Itoa(-1, "-1"); + + Check64BitBase16Itoa(0, "0"); + Check64BitBase10Itoa(0, "0"); + Check64BitBase2Itoa(0, "0"); + + Check64BitBase16Itoa(42, "2a"); + Check64BitBase10Itoa(42, "42"); + Check64BitBase2Itoa(42, "101010"); + + Check64BitBase16Itoa( + std::numeric_limits<int64_t>::max(), "7fffffffffffffff"); + Check64BitBase10Itoa( + std::numeric_limits<int64_t>::max(), "9223372036854775807"); + Check64BitBase2Itoa( + std::numeric_limits<int64_t>::max(), + "111111111111111111111111111111111111111111111111111111111111111"); +} + +#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + diff --git a/pdfium.gyp b/pdfium.gyp index 2ced8e4d9e..7255079598 100644 --- a/pdfium.gyp +++ b/pdfium.gyp @@ -718,6 +718,7 @@ 'core/src/fxcrt/fx_basic_bstring_unittest.cpp', 'core/src/fxcrt/fx_basic_memmgr_unittest.cpp', 'core/src/fxcrt/fx_basic_wstring_unittest.cpp', + 'core/src/fxcrt/fx_system_unittest.cpp', 'testing/fx_string_testhelpers.h', 'testing/fx_string_testhelpers.cpp', ], |