Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
fx_system_unittest.cpp
Go to the documentation of this file.
1// Copyright 2015 The PDFium Authors
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 <math.h>
6
7#include <iterator>
8#include <limits>
9
10#include "build/build_config.h"
11#include "core/fxcrt/fx_string.h"
12#include "core/fxcrt/fx_system.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15// Unit test covering cases where PDFium replaces well-known library
16// functionality on any given platformn.
17
18#if !BUILDFLAG(IS_WIN)
19
20namespace {
21
22const char kSentinel = 0x7f;
23
24void Check32BitBase16Itoa(int32_t input, const char* expected_output) {
25 const size_t kBufLen = 11; // "-" + 8 digits + NUL + sentinel.
26 char buf[kBufLen];
27 buf[kBufLen - 1] = kSentinel;
28 FXSYS_itoa(input, buf, 16);
29 EXPECT_STREQ(expected_output, buf);
30 EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
31}
32
33void Check32BitBase10Itoa(int32_t input, const char* expected_output) {
34 const size_t kBufLen = 13; // "-" + 10 digits + NUL + sentinel.
35 char buf[kBufLen];
36 buf[kBufLen - 1] = kSentinel;
37 FXSYS_itoa(input, buf, 10);
38 EXPECT_STREQ(expected_output, buf);
39 EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
40}
41
42void Check32BitBase2Itoa(int32_t input, const char* expected_output) {
43 const size_t kBufLen = 35; // "-" + 32 digits + NUL + sentinel.
44 char buf[kBufLen];
45 buf[kBufLen - 1] = kSentinel;
46 FXSYS_itoa(input, buf, 2);
47 EXPECT_STREQ(expected_output, buf);
48 EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
49}
50
51void Check64BitBase16Itoa(int64_t input, const char* expected_output) {
52 const size_t kBufLen = 19; // "-" + 16 digits + NUL + sentinel.
53 char buf[kBufLen];
54 buf[kBufLen - 1] = kSentinel;
55 FXSYS_i64toa(input, buf, 16);
56 EXPECT_STREQ(expected_output, buf);
57 EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
58}
59
60void Check64BitBase10Itoa(int64_t input, const char* expected_output) {
61 const size_t kBufLen = 22; // "-" + 19 digits + NUL + sentinel.
62 char buf[kBufLen];
63 buf[kBufLen - 1] = kSentinel;
64 FXSYS_i64toa(input, buf, 10);
65 EXPECT_STREQ(expected_output, buf);
66 EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
67}
68
69void Check64BitBase2Itoa(int64_t input, const char* expected_output) {
70 const size_t kBufLen = 67; // "-" + 64 digits + NUL + sentinel.
71 char buf[kBufLen];
72 buf[kBufLen - 1] = kSentinel;
73 FXSYS_i64toa(input, buf, 2);
74 EXPECT_STREQ(expected_output, buf);
75 EXPECT_EQ(kSentinel, buf[kBufLen - 1]);
76}
77
78} // namespace
79
80TEST(fxcrt, FXSYS_roundf) {
81 EXPECT_EQ(0, FXSYS_roundf(0.0f));
82 EXPECT_EQ(0, FXSYS_roundf(-0.0f));
83 EXPECT_EQ(0, FXSYS_roundf(0.00001f));
84 EXPECT_EQ(0, FXSYS_roundf(-0.00001f));
85 EXPECT_EQ(3, FXSYS_roundf(3.14159f));
86 EXPECT_EQ(4, FXSYS_roundf(3.5f));
87
88 // Check for smallest non-zero float values.
89 EXPECT_EQ(0, FXSYS_roundf(std::numeric_limits<float>::min()));
90 EXPECT_EQ(0, FXSYS_roundf(-std::numeric_limits<float>::min()));
91
92 // Function is a wrapper around standard C library function round(), so
93 // returns the integral value that is nearest to x, with halfway cases
94 // rounded away from zero.
95 EXPECT_EQ(-3, FXSYS_roundf(-3.14159f));
96 EXPECT_EQ(-4, FXSYS_roundf(-3.5f));
97
98 // Positive rounding stops at maximum int.
99 // MAX_INT=0x7FFFFFFF=2147483647=2.147483647e+9
100 // In IEEE-754 format, 2^31 yields exponent of 0x9E with mantissa of all
101 // zeroes which is 0x4f000000=2.14748365e+9, which is beyond max integer.
102 // Going to next smallest float by minus one from exponent and mantissa of
103 // all ones yields binary float representation of 0x4EFFFFFF=2.14748352e+9,
104 // which is 2147483520.
105 EXPECT_EQ(2147483520, FXSYS_roundf(2.14748352e+9f));
106
107 // Using a slightly larger value, expect to see it be capped at MAX_INT.
108 EXPECT_EQ(2147483647, FXSYS_roundf(2.14748365e+9f));
109
110 EXPECT_EQ(2147483647, FXSYS_roundf(2.14748365e+10f));
111 EXPECT_EQ(2147483647, FXSYS_roundf(std::numeric_limits<float>::max()));
112
113 // Negative rounding stops at minimum int.
114 // MIN_INT=0x80000000=-2147483648,=-2.147483648e+9
115 // In IEEE-754 format, 2^31 yields exponent of 0x9E with mantissa of all
116 // zeroes which is 0x4f000000=2.14748365e+9, and the sign bit set, which
117 // is 0xCF000000 and exactly matches the minimum integer. Going to next
118 // smallest negative float by minus one from exponent and mantissa of all
119 // ones yields binary float representation of 0xCEFFFFFF=-2.14748352e+9,
120 // which is -2147483520.
121 EXPECT_EQ(-2147483648, FXSYS_roundf(-2.147483648e+10f));
122 EXPECT_EQ(-2147483648, FXSYS_roundf(-2.147483648e+9f));
123 EXPECT_EQ(-2147483520, FXSYS_roundf(-2.14748352e+9f));
124 EXPECT_EQ(-2147483648, FXSYS_roundf(-std::numeric_limits<float>::max()));
125
126 // NaN should give zero.
127 EXPECT_EQ(0, FXSYS_roundf(NAN));
128}
129
130TEST(fxcrt, FXSYS_round) {
131 EXPECT_EQ(0, FXSYS_round(0.0));
132 EXPECT_EQ(0, FXSYS_round(-0.0));
133 EXPECT_EQ(0, FXSYS_round(0.00001));
134 EXPECT_EQ(0, FXSYS_round(-0.00001));
135 EXPECT_EQ(3, FXSYS_round(3.14159));
136 EXPECT_EQ(4, FXSYS_round(3.5));
137
138 // Check for smallest non-zero double values.
139 EXPECT_EQ(0, FXSYS_round(std::numeric_limits<double>::min()));
140 EXPECT_EQ(0, FXSYS_round(-std::numeric_limits<double>::min()));
141
142 // Function is a wrapper around standard C library function round(), so
143 // returns the integral value that is nearest to x, with halfway cases
144 // rounded away from zero.
145 EXPECT_EQ(-3, FXSYS_round(-3.14159));
146 EXPECT_EQ(-4, FXSYS_round(-3.5));
147
148 // Positive rounding stops at maximum int.
149 // MAX_INT=0x7FFFFFFF=2147483647=2.147483647e+9
150 // In IEEE-754 double precision format, 2^31 yields exponent of 0x41E with
151 // mantissa of all zeroes which is 0x41E0000000000000=2.14748365e+9, which
152 // is beyond max integer.
153 // Going to next smallest float by minus one from exponent and mantissa of
154 // all ones yields binary float representation of
155 // 41DFFFFFFFC00000=2.147483647e+9, which matches the max integer.
156 EXPECT_EQ(2147483647, FXSYS_round(2.147483647e+9));
157
158 // Using a slightly larger value, expect to see it be capped at MAX_INT.
159 EXPECT_EQ(2147483647, FXSYS_round(2.14748365e+9));
160
161 EXPECT_EQ(2147483647, FXSYS_round(2.14748365e+10));
162 EXPECT_EQ(2147483647, FXSYS_round(std::numeric_limits<double>::max()));
163
164 // Negative rounding stops at minimum int.
165 // MIN_INT=0x80000000=-2147483648,=-2.147483648e+9
166 // In IEEE-754 double precision format, 2^31 yields exponent of 0x41E with
167 // mantissa of all zeroes which is 0x41E0000000000000=2.14748365e+9, and the
168 // sign bit set, which is 0xC1E0000000000000 and exactly matches the minimum
169 // integer. Going to next smallest negative double by minus one from
170 // exponent and mantissa of all ones yields binary float representation of
171 // 0xC1DFFFFFFFFFFFFF=-2.1474836479999998e+9, which is -2147483648.
172 EXPECT_EQ(-2147483648, FXSYS_round(-2.1474836479999998e+9));
173 EXPECT_EQ(-2147483648, FXSYS_round(-2.147483648e+9));
174 EXPECT_EQ(-2147483648, FXSYS_round(-2.147483648e+10));
175 EXPECT_EQ(-2147483648, FXSYS_round(-std::numeric_limits<double>::max()));
176
177 // NaN should give zero.
178 EXPECT_EQ(0, FXSYS_round(NAN));
179}
180
181TEST(fxcrt, FXSYS_itoa_InvalidRadix) {
182 char buf[32];
183
184 FXSYS_itoa(42, buf, 17); // Ours stops at 16.
185 EXPECT_STREQ("", buf);
186
187 FXSYS_itoa(42, buf, 1);
188 EXPECT_STREQ("", buf);
189
190 FXSYS_itoa(42, buf, 0);
191 EXPECT_STREQ("", buf);
192
193 FXSYS_itoa(42, buf, -1);
194 EXPECT_STREQ("", buf);
195}
196
197TEST(fxcrt, FXSYS_itoa) {
198 Check32BitBase16Itoa(std::numeric_limits<int32_t>::min(), "-80000000");
199 Check32BitBase10Itoa(std::numeric_limits<int32_t>::min(), "-2147483648");
200 Check32BitBase2Itoa(std::numeric_limits<int32_t>::min(),
201 "-10000000000000000000000000000000");
202
203 Check32BitBase16Itoa(-1, "-1");
204 Check32BitBase10Itoa(-1, "-1");
205 Check32BitBase2Itoa(-1, "-1");
206
207 Check32BitBase16Itoa(0, "0");
208 Check32BitBase10Itoa(0, "0");
209 Check32BitBase2Itoa(0, "0");
210
211 Check32BitBase16Itoa(42, "2a");
212 Check32BitBase10Itoa(42, "42");
213 Check32BitBase2Itoa(42, "101010");
214
215 Check32BitBase16Itoa(std::numeric_limits<int32_t>::max(), "7fffffff");
216 Check32BitBase10Itoa(std::numeric_limits<int32_t>::max(), "2147483647");
217 Check32BitBase2Itoa(std::numeric_limits<int32_t>::max(),
218 "1111111111111111111111111111111");
219}
220
221TEST(fxcrt, FXSYS_i64toa_InvalidRadix) {
222 char buf[32];
223
224 FXSYS_i64toa(42, buf, 17); // Ours stops at 16.
225 EXPECT_STREQ("", buf);
226
227 FXSYS_i64toa(42, buf, 1);
228 EXPECT_STREQ("", buf);
229
230 FXSYS_i64toa(42, buf, 0);
231 EXPECT_STREQ("", buf);
232
233 FXSYS_i64toa(42, buf, -1);
234 EXPECT_STREQ("", buf);
235}
236
237TEST(fxcrt, FXSYS_i64toa) {
238 Check64BitBase16Itoa(std::numeric_limits<int64_t>::min(),
239 "-8000000000000000");
240 Check64BitBase10Itoa(std::numeric_limits<int64_t>::min(),
241 "-9223372036854775808");
242 Check64BitBase2Itoa(
243 std::numeric_limits<int64_t>::min(),
244 "-1000000000000000000000000000000000000000000000000000000000000000");
245
246 Check64BitBase16Itoa(-1, "-1");
247 Check64BitBase10Itoa(-1, "-1");
248 Check64BitBase2Itoa(-1, "-1");
249
250 Check64BitBase16Itoa(0, "0");
251 Check64BitBase10Itoa(0, "0");
252 Check64BitBase2Itoa(0, "0");
253
254 Check64BitBase16Itoa(42, "2a");
255 Check64BitBase10Itoa(42, "42");
256 Check64BitBase2Itoa(42, "101010");
257
258 Check64BitBase16Itoa(std::numeric_limits<int64_t>::max(), "7fffffffffffffff");
259 Check64BitBase10Itoa(std::numeric_limits<int64_t>::max(),
260 "9223372036854775807");
261 Check64BitBase2Itoa(
262 std::numeric_limits<int64_t>::max(),
263 "111111111111111111111111111111111111111111111111111111111111111");
264}
265
266#endif // !BUILDFLAG(IS_WIN)
267
269 struct tm good_time = {};
270 good_time.tm_year = 74; // 1900-based.
271 good_time.tm_mon = 7; // 0-based.
272 good_time.tm_mday = 9; // 1-based.
273 good_time.tm_hour = 11;
274 good_time.tm_min = 59;
275 good_time.tm_sec = 59;
276
277 wchar_t buf[100] = {};
278 EXPECT_EQ(19u, FXSYS_wcsftime(buf, std::size(buf), L"%Y-%m-%dT%H:%M:%S",
279 &good_time));
280 EXPECT_STREQ(L"1974-08-09T11:59:59", buf);
281
282 // Ensure wcsftime handles a wide range of years without crashing.
283 struct tm year_time = {};
284 year_time.tm_mon = 7; // 0-based.
285 year_time.tm_mday = 9; // 1-based.
286 year_time.tm_hour = 11;
287 year_time.tm_min = 59;
288 year_time.tm_sec = 59;
289
290 for (int year = -2500; year <= 8500; ++year) {
291 year_time.tm_year = year;
292 wchar_t year_buf[100] = {};
293 FXSYS_wcsftime(year_buf, std::size(year_buf), L"%Y-%m-%dT%H:%M:%S",
294 &year_time);
295 }
296
297 // Ensure wcsftime handles bad years, etc. without crashing.
298 struct tm bad_time = {};
299 bad_time.tm_year = -1;
300 bad_time.tm_mon = -1;
301 bad_time.tm_mday = -1;
302 bad_time.tm_hour = -1;
303 bad_time.tm_min = -1;
304 bad_time.tm_sec = -1;
305
306 FXSYS_wcsftime(buf, std::size(buf), L"%y-%m-%dT%H:%M:%S", &bad_time);
307
308 // Ensure wcsftime handles bad-ish day without crashing (Feb 30).
309 struct tm feb_time = {};
310 feb_time.tm_year = 115; // 1900-based.
311 feb_time.tm_mon = 1; // 0-based.
312 feb_time.tm_mday = 30; // 1-based.
313 feb_time.tm_hour = 12;
314 feb_time.tm_min = 00;
315 feb_time.tm_sec = 00;
316
317 FXSYS_wcsftime(buf, std::size(buf), L"%y-%m-%dT%H:%M:%S", &feb_time);
318}
319
320TEST(fxcrt, FXSYS_atoi) {
321 EXPECT_EQ(0, FXSYS_atoi(""));
322 EXPECT_EQ(0, FXSYS_atoi("0"));
323 EXPECT_EQ(-1, FXSYS_atoi("-1"));
324 EXPECT_EQ(2345, FXSYS_atoi("2345"));
325 EXPECT_EQ(-2147483647, FXSYS_atoi("-2147483647"));
326 // Handle the sign.
327 EXPECT_EQ(-2345, FXSYS_atoi("-2345"));
328 EXPECT_EQ(2345, FXSYS_atoi("+2345"));
329 // The max value.
330 EXPECT_EQ(2147483647, FXSYS_atoi("2147483647"));
331 // The min value. Written in -1 format to avoid "unary minus operator applied
332 // to unsigned type" warning.
333 EXPECT_EQ(-2147483647 - 1, FXSYS_atoi("-2147483648"));
334 // With invalid char.
335 EXPECT_EQ(9, FXSYS_atoi("9x9"));
336
337 // Out of range values.
338 EXPECT_EQ(2147483647, FXSYS_atoi("2147483623423412348"));
339 EXPECT_EQ(2147483647, FXSYS_atoi("2147483648"));
340 EXPECT_EQ(-2147483647 - 1, FXSYS_atoi("-2147483650"));
341}
342
343TEST(fxcrt, FXSYS_atoi64) {
344 EXPECT_EQ(0, FXSYS_atoi64(""));
345 EXPECT_EQ(0, FXSYS_atoi64("0"));
346 EXPECT_EQ(-1, FXSYS_atoi64("-1"));
347 EXPECT_EQ(2345, FXSYS_atoi64("2345"));
348 EXPECT_EQ(-9223372036854775807LL, FXSYS_atoi64("-9223372036854775807"));
349 // Handle the sign.
350 EXPECT_EQ(-2345, FXSYS_atoi64("-2345"));
351 EXPECT_EQ(2345, FXSYS_atoi64("+2345"));
352 // The max value.
353 EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("9223372036854775807"));
354 // The min value. Written in -1 format to avoid implicit unsigned warning.
355 EXPECT_EQ(-9223372036854775807LL - 1LL, FXSYS_atoi64("-9223372036854775808"));
356 // With invalid char.
357 EXPECT_EQ(9, FXSYS_atoi64("9x9"));
358
359 // Out of range values.
360 EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("922337203685471234123475807"));
361 EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("9223372036854775808"));
362 EXPECT_EQ(-9223372036854775807LL - 1LL, FXSYS_atoi64("-9223372036854775810"));
363}
364
365TEST(fxcrt, FXSYS_wtoi) {
366 EXPECT_EQ(0, FXSYS_wtoi(L""));
367 EXPECT_EQ(0, FXSYS_wtoi(L"0"));
368 EXPECT_EQ(-1, FXSYS_wtoi(L"-1"));
369 EXPECT_EQ(2345, FXSYS_wtoi(L"2345"));
370 EXPECT_EQ(-2147483647, FXSYS_wtoi(L"-2147483647"));
371 // The max value.
372 EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483647"));
373 // The min value.
374 EXPECT_EQ(-2147483647 - 1, FXSYS_wtoi(L"-2147483648"));
375
376 // Out of range values.
377 EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483623423412348"));
378 EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483648"));
379 EXPECT_EQ(-2147483647 - 1, FXSYS_wtoi(L"-2147483652"));
380}
381
382TEST(fxcrt, FXSYS_atoui) {
383 EXPECT_EQ(0u, FXSYS_atoui(""));
384 EXPECT_EQ(0u, FXSYS_atoui("0"));
385 EXPECT_EQ(4294967295, FXSYS_atoui("-1"));
386 EXPECT_EQ(2345u, FXSYS_atoui("2345"));
387 // Handle the sign.
388 EXPECT_EQ(4294964951, FXSYS_atoui("-2345"));
389 EXPECT_EQ(2345u, FXSYS_atoui("+2345"));
390 // The max value.
391 EXPECT_EQ(4294967295, FXSYS_atoui("4294967295"));
392 EXPECT_EQ(9u, FXSYS_atoui("9x9"));
393
394 // Out of range values.
395 EXPECT_EQ(4294967295, FXSYS_atoui("2147483623423412348"));
396 EXPECT_EQ(4294967295, FXSYS_atoui("4294967296"));
397 EXPECT_EQ(4294967295, FXSYS_atoui("-4294967345"));
398}
TEST(FXCRYPT, CryptToBase16)
#define FXSYS_wcsftime
Definition fx_system.h:75