summaryrefslogtreecommitdiff
path: root/core/src/fxcrt
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fxcrt')
-rw-r--r--core/src/fxcrt/fx_arabic.cpp27
-rw-r--r--core/src/fxcrt/fx_basic_gcc.cpp38
-rw-r--r--core/src/fxcrt/fx_system_unittest.cpp161
-rw-r--r--core/src/fxcrt/fx_ucddata.cpp19
-rw-r--r--core/src/fxcrt/fx_unicode.cpp27
5 files changed, 224 insertions, 48 deletions
diff --git a/core/src/fxcrt/fx_arabic.cpp b/core/src/fxcrt/fx_arabic.cpp
index ab736f9769..139e9f1f48 100644
--- a/core/src/fxcrt/fx_arabic.cpp
+++ b/core/src/fxcrt/fx_arabic.cpp
@@ -7,7 +7,6 @@
#include "../../include/fxcrt/fx_ucd.h"
#include "fx_arabic.h"
-extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536];
#ifdef __cplusplus
extern "C" {
#endif
@@ -149,19 +148,19 @@ IFX_ArabicChar* IFX_ArabicChar::Create() {
}
FX_BOOL CFX_ArabicChar::IsArabicChar(FX_WCHAR wch) const {
FX_DWORD dwRet =
- (gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & FX_CHARTYPEBITSMASK);
+ kTextLayoutCodeProperties[(FX_WORD)wch] & FX_CHARTYPEBITSMASK;
return dwRet >= FX_CHARTYPE_ArabicAlef;
}
FX_BOOL CFX_ArabicChar::IsArabicFormChar(FX_WCHAR wch) const {
- return (gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] &
- FX_CHARTYPEBITSMASK) == FX_CHARTYPE_ArabicForm;
+ return (kTextLayoutCodeProperties[(FX_WORD)wch] & FX_CHARTYPEBITSMASK) ==
+ FX_CHARTYPE_ArabicForm;
}
FX_WCHAR CFX_ArabicChar::GetFormChar(FX_WCHAR wch,
FX_WCHAR prev,
FX_WCHAR next) const {
- CFX_Char c(wch, gs_FX_TextLayout_CodeProperties[(FX_WORD)wch]);
- CFX_Char p(prev, gs_FX_TextLayout_CodeProperties[(FX_WORD)prev]);
- CFX_Char n(next, gs_FX_TextLayout_CodeProperties[(FX_WORD)next]);
+ CFX_Char c(wch, kTextLayoutCodeProperties[(FX_WORD)wch]);
+ CFX_Char p(prev, kTextLayoutCodeProperties[(FX_WORD)prev]);
+ CFX_Char n(next, kTextLayoutCodeProperties[(FX_WORD)next]);
return GetFormChar(&c, &p, &n);
}
FX_WCHAR CFX_ArabicChar::GetFormChar(const CFX_Char* cur,
@@ -260,17 +259,17 @@ void FX_BidiClassify(const CFX_WideString& wsText,
if (bWS) {
for (int32_t i = 0; i < iCount; i++) {
wch = *pwsStart++;
- iCls = ((gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] &
- FX_BIDICLASSBITSMASK) >>
- FX_BIDICLASSBITS);
+ iCls =
+ ((kTextLayoutCodeProperties[(FX_WORD)wch] & FX_BIDICLASSBITSMASK) >>
+ FX_BIDICLASSBITS);
classes.SetAt(i, iCls);
}
} else {
for (int32_t i = 0; i < iCount; i++) {
wch = *pwsStart++;
- iCls = ((gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] &
- FX_BIDICLASSBITSMASK) >>
- FX_BIDICLASSBITS);
+ iCls =
+ ((kTextLayoutCodeProperties[(FX_WORD)wch] & FX_BIDICLASSBITSMASK) >>
+ FX_BIDICLASSBITS);
classes.SetAt(i, gc_FX_BidiNTypes[iCls]);
}
}
@@ -1070,7 +1069,7 @@ void CFX_BidiChar::SetPolicy(FX_BOOL bSeparateNeutral) {
}
FX_BOOL CFX_BidiChar::AppendChar(FX_WCHAR wch) {
- FX_DWORD dwProps = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch];
+ FX_DWORD dwProps = kTextLayoutCodeProperties[(FX_WORD)wch];
int32_t iBidiCls = (dwProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS;
int32_t iContext = 0;
switch (iBidiCls) {
diff --git a/core/src/fxcrt/fx_basic_gcc.cpp b/core/src/fxcrt/fx_basic_gcc.cpp
index bf3d61524e..6f17482156 100644
--- a/core/src/fxcrt/fx_basic_gcc.cpp
+++ b/core/src/fxcrt/fx_basic_gcc.cpp
@@ -32,30 +32,41 @@ 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
@@ -72,10 +83,7 @@ int64_t FXSYS_wtoi64(const FX_WCHAR* str) {
return FXSYS_StrToInt<int64_t, 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
}
@@ -182,7 +190,7 @@ int FXSYS_wcsicmp(const FX_WCHAR* dst, const FX_WCHAR* src) {
return (f - l);
}
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..824ed5370c
--- /dev/null
+++ b/core/src/fxcrt/fx_system_unittest.cpp
@@ -0,0 +1,161 @@
+// 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/core/src/fxcrt/fx_ucddata.cpp b/core/src/fxcrt/fx_ucddata.cpp
index 8b35f31e2b..13c5da1419 100644
--- a/core/src/fxcrt/fx_ucddata.cpp
+++ b/core/src/fxcrt/fx_ucddata.cpp
@@ -4,9 +4,10 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#include "../../include/fxcrt/fx_system.h"
+#include "../../include/fxcrt/fx_basic.h"
+#include "../../include/fxcrt/fx_ucd.h"
-extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536] = {
+const FX_DWORD kTextLayoutCodeProperties[] = {
0xfffe9a93, 0xfffe9a93, 0xfffe9a93, 0xfffe9a93, 0xfffe9a93, 0xfffe9a93,
0xfffe9a93, 0xfffe9a93, 0xfffe9a93, 0xfffe8ae5, 0xfffe9b5c, 0xfffe9ada,
0xfffe9b1a, 0xfffe9b5b, 0xfffe9a93, 0xfffe9a93, 0xfffe9a93, 0xfffe9a93,
@@ -10931,7 +10932,11 @@ extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536] = {
0xfffe02a4, 0xfffe02a4, 0xfffe02a4, 0xfffe3013, 0xfffe3013, 0xfffe3013,
0xfffe3011, 0xfffe3022, 0xfffe1aa4, 0xfffe1aa4,
};
-extern const FX_WCHAR gs_FX_TextLayout_VerticalMirror[64] = {
+
+const size_t kTextLayoutCodePropertiesSize =
+ FX_ArraySize(kTextLayoutCodeProperties);
+
+const FX_WCHAR kFXTextLayoutVerticalMirror[] = {
0xFE33, 0xFE32, 0xFE31, 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xFE3F,
0xFE40, 0xFE3D, 0xFE3E, 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xFE3B,
0xFE3C, 0xFE39, 0xFE3A, 0xFE34, 0xFE35, 0xFE36, 0xFE37, 0xFE38,
@@ -10941,7 +10946,10 @@ extern const FX_WCHAR gs_FX_TextLayout_VerticalMirror[64] = {
0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF,
0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF,
};
-extern const FX_WCHAR gs_FX_TextLayout_BidiMirror[512] = {
+const size_t kFXTextLayoutVerticalMirrorSize =
+ FX_ArraySize(kFXTextLayoutVerticalMirror);
+
+const FX_WCHAR kFXTextLayoutBidiMirror[] = {
0x0029, 0x0028, 0x003E, 0x003C, 0x005D, 0x005B, 0x007D, 0x007B, 0x00BB,
0x00AB, 0x0F3B, 0x0F3A, 0x0F3D, 0x0F3C, 0x169C, 0x169B, 0x2019, 0x2018,
0x201D, 0x201C, 0x203A, 0x2039, 0x2046, 0x2045, 0x207E, 0x207D, 0x208E,
@@ -11000,3 +11008,6 @@ extern const FX_WCHAR gs_FX_TextLayout_BidiMirror[512] = {
0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF,
0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF, 0xFEFF,
};
+
+const size_t kFXTextLayoutBidiMirrorSize =
+ FX_ArraySize(kFXTextLayoutBidiMirror);
diff --git a/core/src/fxcrt/fx_unicode.cpp b/core/src/fxcrt/fx_unicode.cpp
index f05aeb5efb..67ff009513 100644
--- a/core/src/fxcrt/fx_unicode.cpp
+++ b/core/src/fxcrt/fx_unicode.cpp
@@ -6,41 +6,38 @@
#include "../../include/fxcrt/fx_ucd.h"
-extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536];
-extern const FX_WCHAR gs_FX_TextLayout_VerticalMirror[64];
-extern const FX_WCHAR gs_FX_TextLayout_BidiMirror[512];
FX_DWORD FX_GetUnicodeProperties(FX_WCHAR wch) {
- return gs_FX_TextLayout_CodeProperties[(FX_WORD)wch];
+ return kTextLayoutCodeProperties[(FX_WORD)wch];
}
FX_BOOL FX_IsCtrlCode(FX_WCHAR ch) {
FX_DWORD dwRet =
- (gs_FX_TextLayout_CodeProperties[(FX_WORD)ch] & FX_CHARTYPEBITSMASK);
+ (kTextLayoutCodeProperties[(FX_WORD)ch] & FX_CHARTYPEBITSMASK);
return dwRet == FX_CHARTYPE_Tab || dwRet == FX_CHARTYPE_Control;
}
FX_BOOL FX_IsRotationCode(FX_WCHAR ch) {
- return (gs_FX_TextLayout_CodeProperties[(FX_WORD)ch] & 0x8000) != 0;
+ return (kTextLayoutCodeProperties[(FX_WORD)ch] & 0x8000) != 0;
}
FX_BOOL FX_IsCombinationChar(FX_WCHAR wch) {
FX_DWORD dwProps =
- (gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & FX_CHARTYPEBITSMASK);
+ (kTextLayoutCodeProperties[(FX_WORD)wch] & FX_CHARTYPEBITSMASK);
return dwProps == FX_CHARTYPE_Combination;
}
FX_BOOL FX_IsBidiChar(FX_WCHAR wch) {
- FX_DWORD dwProps = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch];
+ FX_DWORD dwProps = kTextLayoutCodeProperties[(FX_WORD)wch];
int32_t iBidiCls = (dwProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS;
return (FX_BIDICLASS_R == iBidiCls || FX_BIDICLASS_AL == iBidiCls);
}
FX_WCHAR FX_GetMirrorChar(FX_WCHAR wch, FX_BOOL bRTL, FX_BOOL bVertical) {
- FX_DWORD dwProps = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch];
+ FX_DWORD dwProps = kTextLayoutCodeProperties[(FX_WORD)wch];
FX_DWORD dwTemp = (dwProps & 0xFF800000);
if (bRTL && dwTemp < 0xFF800000) {
- wch = gs_FX_TextLayout_BidiMirror[dwTemp >> 23];
- dwProps = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch];
+ wch = kFXTextLayoutBidiMirror[dwTemp >> 23];
+ dwProps = kTextLayoutCodeProperties[(FX_WORD)wch];
}
if (bVertical) {
dwTemp = (dwProps & 0x007E0000);
if (dwTemp < 0x007E0000) {
- wch = gs_FX_TextLayout_VerticalMirror[dwTemp >> 17];
+ wch = kFXTextLayoutVerticalMirror[dwTemp >> 17];
}
}
return wch;
@@ -51,13 +48,13 @@ FX_WCHAR FX_GetMirrorChar(FX_WCHAR wch,
FX_BOOL bVertical) {
FX_DWORD dwTemp = (dwProps & 0xFF800000);
if (bRTL && dwTemp < 0xFF800000) {
- wch = gs_FX_TextLayout_BidiMirror[dwTemp >> 23];
- dwProps = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch];
+ wch = kFXTextLayoutBidiMirror[dwTemp >> 23];
+ dwProps = kTextLayoutCodeProperties[(FX_WORD)wch];
}
if (bVertical) {
dwTemp = (dwProps & 0x007E0000);
if (dwTemp < 0x007E0000) {
- wch = gs_FX_TextLayout_VerticalMirror[dwTemp >> 17];
+ wch = kFXTextLayoutVerticalMirror[dwTemp >> 17];
}
}
return wch;