Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2015 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <limits>
      6 
      7 #include "core/fxcrt/fx_string.h"
      8 #include "core/fxcrt/fx_system.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 // Unit test covering cases where PDFium replaces well-known library
     12 // functionality on any given platformn.
     13 
     14 #if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
     15 
     16 namespace {
     17 
     18 const char kSentinel = 0x7f;
     19 
     20 void Check32BitBase16Itoa(int32_t input, const char* expected_output) {
     21   const size_t kBufLen = 11;  // "-" + 8 digits + NUL + sentinel.
     22   char buf[kBufLen];
     23   buf[kBufLen - 1] = kSentinel;
     24   FXSYS_itoa(input, buf, 16);
     25   EXPECT_STREQ(expected_output, buf);
     26   EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
     27 }
     28 
     29 void Check32BitBase10Itoa(int32_t input, const char* expected_output) {
     30   const size_t kBufLen = 13;  // "-" + 10 digits + NUL + sentinel.
     31   char buf[kBufLen];
     32   buf[kBufLen - 1] = kSentinel;
     33   FXSYS_itoa(input, buf, 10);
     34   EXPECT_STREQ(expected_output, buf);
     35   EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
     36 }
     37 
     38 void Check32BitBase2Itoa(int32_t input, const char* expected_output) {
     39   const size_t kBufLen = 35;  // "-" + 32 digits + NUL + sentinel.
     40   char buf[kBufLen];
     41   buf[kBufLen - 1] = kSentinel;
     42   FXSYS_itoa(input, buf, 2);
     43   EXPECT_STREQ(expected_output, buf);
     44   EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
     45 }
     46 
     47 void Check64BitBase16Itoa(int64_t input, const char* expected_output) {
     48   const size_t kBufLen = 19;  // "-" + 16 digits + NUL + sentinel.
     49   char buf[kBufLen];
     50   buf[kBufLen - 1] = kSentinel;
     51   FXSYS_i64toa(input, buf, 16);
     52   EXPECT_STREQ(expected_output, buf);
     53   EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
     54 }
     55 
     56 void Check64BitBase10Itoa(int64_t input, const char* expected_output) {
     57   const size_t kBufLen = 22;  // "-" + 19 digits + NUL + sentinel.
     58   char buf[kBufLen];
     59   buf[kBufLen - 1] = kSentinel;
     60   FXSYS_i64toa(input, buf, 10);
     61   EXPECT_STREQ(expected_output, buf);
     62   EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
     63 }
     64 
     65 void Check64BitBase2Itoa(int64_t input, const char* expected_output) {
     66   const size_t kBufLen = 67;  // "-" + 64 digits + NUL + sentinel.
     67   char buf[kBufLen];
     68   buf[kBufLen - 1] = kSentinel;
     69   FXSYS_i64toa(input, buf, 2);
     70   EXPECT_STREQ(expected_output, buf);
     71   EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
     72 }
     73 
     74 }  // namespace
     75 
     76 TEST(fxcrt, FXSYS_itoa_InvalidRadix) {
     77   char buf[32];
     78 
     79   FXSYS_itoa(42, buf, 17);  // Ours stops at 16.
     80   EXPECT_STREQ("", buf);
     81 
     82   FXSYS_itoa(42, buf, 1);
     83   EXPECT_STREQ("", buf);
     84 
     85   FXSYS_itoa(42, buf, 0);
     86   EXPECT_STREQ("", buf);
     87 
     88   FXSYS_itoa(42, buf, -1);
     89   EXPECT_STREQ("", buf);
     90 }
     91 
     92 TEST(fxcrt, FXSYS_itoa) {
     93   Check32BitBase16Itoa(std::numeric_limits<int32_t>::min(), "-80000000");
     94   Check32BitBase10Itoa(std::numeric_limits<int32_t>::min(), "-2147483648");
     95   Check32BitBase2Itoa(std::numeric_limits<int32_t>::min(),
     96                       "-10000000000000000000000000000000");
     97 
     98   Check32BitBase16Itoa(-1, "-1");
     99   Check32BitBase10Itoa(-1, "-1");
    100   Check32BitBase2Itoa(-1, "-1");
    101 
    102   Check32BitBase16Itoa(0, "0");
    103   Check32BitBase10Itoa(0, "0");
    104   Check32BitBase2Itoa(0, "0");
    105 
    106   Check32BitBase16Itoa(42, "2a");
    107   Check32BitBase10Itoa(42, "42");
    108   Check32BitBase2Itoa(42, "101010");
    109 
    110   Check32BitBase16Itoa(std::numeric_limits<int32_t>::max(), "7fffffff");
    111   Check32BitBase10Itoa(std::numeric_limits<int32_t>::max(), "2147483647");
    112   Check32BitBase2Itoa(std::numeric_limits<int32_t>::max(),
    113                       "1111111111111111111111111111111");
    114 }
    115 
    116 TEST(fxcrt, FXSYS_i64toa_InvalidRadix) {
    117   char buf[32];
    118 
    119   FXSYS_i64toa(42, buf, 17);  // Ours stops at 16.
    120   EXPECT_STREQ("", buf);
    121 
    122   FXSYS_i64toa(42, buf, 1);
    123   EXPECT_STREQ("", buf);
    124 
    125   FXSYS_i64toa(42, buf, 0);
    126   EXPECT_STREQ("", buf);
    127 
    128   FXSYS_i64toa(42, buf, -1);
    129   EXPECT_STREQ("", buf);
    130 }
    131 
    132 TEST(fxcrt, FXSYS_i64toa) {
    133   Check64BitBase16Itoa(std::numeric_limits<int64_t>::min(),
    134                        "-8000000000000000");
    135   Check64BitBase10Itoa(std::numeric_limits<int64_t>::min(),
    136                        "-9223372036854775808");
    137   Check64BitBase2Itoa(
    138       std::numeric_limits<int64_t>::min(),
    139       "-1000000000000000000000000000000000000000000000000000000000000000");
    140 
    141   Check64BitBase16Itoa(-1, "-1");
    142   Check64BitBase10Itoa(-1, "-1");
    143   Check64BitBase2Itoa(-1, "-1");
    144 
    145   Check64BitBase16Itoa(0, "0");
    146   Check64BitBase10Itoa(0, "0");
    147   Check64BitBase2Itoa(0, "0");
    148 
    149   Check64BitBase16Itoa(42, "2a");
    150   Check64BitBase10Itoa(42, "42");
    151   Check64BitBase2Itoa(42, "101010");
    152 
    153   Check64BitBase16Itoa(std::numeric_limits<int64_t>::max(), "7fffffffffffffff");
    154   Check64BitBase10Itoa(std::numeric_limits<int64_t>::max(),
    155                        "9223372036854775807");
    156   Check64BitBase2Itoa(
    157       std::numeric_limits<int64_t>::max(),
    158       "111111111111111111111111111111111111111111111111111111111111111");
    159 }
    160 
    161 #endif  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
    162 
    163 TEST(fxcrt, FXSYS_wcsftime) {
    164   struct tm good_time = {};
    165   good_time.tm_year = 74;  // 1900-based.
    166   good_time.tm_mon = 7;    // 0-based.
    167   good_time.tm_mday = 9;   // 1-based.
    168   good_time.tm_hour = 11;
    169   good_time.tm_min = 59;
    170   good_time.tm_sec = 59;
    171 
    172   wchar_t buf[100] = {};
    173   EXPECT_EQ(19u, FXSYS_wcsftime(buf, FX_ArraySize(buf), L"%Y-%m-%dT%H:%M:%S",
    174                                 &good_time));
    175   EXPECT_STREQ(L"1974-08-09T11:59:59", buf);
    176 
    177   // Ensure wcsftime handles a wide range of years without crashing.
    178   struct tm year_time = {};
    179   year_time.tm_mon = 7;   // 0-based.
    180   year_time.tm_mday = 9;  // 1-based.
    181   year_time.tm_hour = 11;
    182   year_time.tm_min = 59;
    183   year_time.tm_sec = 59;
    184 
    185   for (int year = -2500; year <= 8500; ++year) {
    186     year_time.tm_year = year;
    187     wchar_t year_buf[100] = {};
    188     FXSYS_wcsftime(year_buf, FX_ArraySize(year_buf), L"%Y-%m-%dT%H:%M:%S",
    189                    &year_time);
    190   }
    191 
    192   // Ensure wcsftime handles bad years, etc. without crashing.
    193   struct tm bad_time = {};
    194   bad_time.tm_year = -1;
    195   bad_time.tm_mon = -1;
    196   bad_time.tm_mday = -1;
    197   bad_time.tm_hour = -1;
    198   bad_time.tm_min = -1;
    199   bad_time.tm_sec = -1;
    200 
    201   FXSYS_wcsftime(buf, FX_ArraySize(buf), L"%y-%m-%dT%H:%M:%S", &bad_time);
    202 
    203   // Ensure wcsftime handles bad-ish day without crashing (Feb 30).
    204   struct tm feb_time = {};
    205   feb_time.tm_year = 115;  // 1900-based.
    206   feb_time.tm_mon = 1;     // 0-based.
    207   feb_time.tm_mday = 30;   // 1-based.
    208   feb_time.tm_hour = 12;
    209   feb_time.tm_min = 00;
    210   feb_time.tm_sec = 00;
    211 
    212   FXSYS_wcsftime(buf, FX_ArraySize(buf), L"%y-%m-%dT%H:%M:%S", &feb_time);
    213 }
    214 
    215 TEST(fxcrt, FXSYS_atoi) {
    216   EXPECT_EQ(0, FXSYS_atoi(""));
    217   EXPECT_EQ(0, FXSYS_atoi("0"));
    218   EXPECT_EQ(-1, FXSYS_atoi("-1"));
    219   EXPECT_EQ(2345, FXSYS_atoi("2345"));
    220   EXPECT_EQ(-2147483647, FXSYS_atoi("-2147483647"));
    221   // Handle the sign.
    222   EXPECT_EQ(-2345, FXSYS_atoi("-2345"));
    223   EXPECT_EQ(2345, FXSYS_atoi("+2345"));
    224   // The max value.
    225   EXPECT_EQ(2147483647, FXSYS_atoi("2147483647"));
    226   // The min value. Written in -1 format to avoid "unary minus operator applied
    227   // to unsigned type" warning.
    228   EXPECT_EQ(-2147483647 - 1, FXSYS_atoi("-2147483648"));
    229   // With invalid char.
    230   EXPECT_EQ(9, FXSYS_atoi("9x9"));
    231 
    232   // Out of range values.
    233   EXPECT_EQ(2147483647, FXSYS_atoi("2147483623423412348"));
    234   EXPECT_EQ(2147483647, FXSYS_atoi("2147483648"));
    235   EXPECT_EQ(-2147483647 - 1, FXSYS_atoi("-2147483650"));
    236 }
    237 
    238 TEST(fxcrt, FXSYS_atoi64) {
    239   EXPECT_EQ(0, FXSYS_atoi64(""));
    240   EXPECT_EQ(0, FXSYS_atoi64("0"));
    241   EXPECT_EQ(-1, FXSYS_atoi64("-1"));
    242   EXPECT_EQ(2345, FXSYS_atoi64("2345"));
    243   EXPECT_EQ(-9223372036854775807LL, FXSYS_atoi64("-9223372036854775807"));
    244   // Handle the sign.
    245   EXPECT_EQ(-2345, FXSYS_atoi64("-2345"));
    246   EXPECT_EQ(2345, FXSYS_atoi64("+2345"));
    247   // The max value.
    248   EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("9223372036854775807"));
    249   // The min value. Written in -1 format to avoid implicit unsigned warning.
    250   EXPECT_EQ(-9223372036854775807LL - 1LL, FXSYS_atoi64("-9223372036854775808"));
    251   // With invalid char.
    252   EXPECT_EQ(9, FXSYS_atoi64("9x9"));
    253 
    254   // Out of range values.
    255   EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("922337203685471234123475807"));
    256   EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("9223372036854775808"));
    257   EXPECT_EQ(-9223372036854775807LL - 1LL, FXSYS_atoi64("-9223372036854775810"));
    258 }
    259 
    260 TEST(fxcrt, FXSYS_wtoi) {
    261   EXPECT_EQ(0, FXSYS_wtoi(L""));
    262   EXPECT_EQ(0, FXSYS_wtoi(L"0"));
    263   EXPECT_EQ(-1, FXSYS_wtoi(L"-1"));
    264   EXPECT_EQ(2345, FXSYS_wtoi(L"2345"));
    265   EXPECT_EQ(-2147483647, FXSYS_wtoi(L"-2147483647"));
    266   // The max value.
    267   EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483647"));
    268   // The min value.
    269   EXPECT_EQ(-2147483647 - 1, FXSYS_wtoi(L"-2147483648"));
    270 
    271   // Out of range values.
    272   EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483623423412348"));
    273   EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483648"));
    274   EXPECT_EQ(-2147483647 - 1, FXSYS_wtoi(L"-2147483652"));
    275 }
    276 
    277 TEST(fxcrt, FXSYS_atoui) {
    278   EXPECT_EQ(0u, FXSYS_atoui(""));
    279   EXPECT_EQ(0u, FXSYS_atoui("0"));
    280   EXPECT_EQ(4294967295, FXSYS_atoui("-1"));
    281   EXPECT_EQ(2345u, FXSYS_atoui("2345"));
    282   // Handle the sign.
    283   EXPECT_EQ(4294964951, FXSYS_atoui("-2345"));
    284   EXPECT_EQ(2345u, FXSYS_atoui("+2345"));
    285   // The max value.
    286   EXPECT_EQ(4294967295, FXSYS_atoui("4294967295"));
    287   EXPECT_EQ(9u, FXSYS_atoui("9x9"));
    288 
    289   // Out of range values.
    290   EXPECT_EQ(4294967295, FXSYS_atoui("2147483623423412348"));
    291   EXPECT_EQ(4294967295, FXSYS_atoui("4294967296"));
    292   EXPECT_EQ(4294967295, FXSYS_atoui("-4294967345"));
    293 }
    294