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