]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Test/GoogleTest/Library/BaseSafeIntLib/SafeIntLibUintnIntnUnitTests64.cpp
6fb0710cfed6ceb87339d6ac608ae5b8eca8d703
[mirror_edk2.git] / MdePkg / Test / GoogleTest / Library / BaseSafeIntLib / SafeIntLibUintnIntnUnitTests64.cpp
1 /** @file
2 x64-specific functions for unit-testing INTN and UINTN functions in
3 SafeIntLib.
4
5 Copyright (c) Microsoft Corporation.<BR>
6 Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include <gtest/gtest.h>
12 extern "C" {
13 #include <Base.h>
14 #include <Library/SafeIntLib.h>
15 }
16
17 TEST(ConversionTestSuite, TestSafeInt32ToUintn) {
18 RETURN_STATUS Status;
19 INT32 Operand;
20 UINTN Result;
21
22 //
23 // If Operand is non-negative, then it's a cast
24 //
25 Operand = 0x5bababab;
26 Result = 0;
27 Status = SafeInt32ToUintn (Operand, &Result);
28 ASSERT_EQ (Status, RETURN_SUCCESS);
29 ASSERT_EQ ((UINTN)0x5bababab, Result);
30
31 //
32 // Otherwise should result in an error status
33 //
34 Operand = (-1537977259);
35 Status = SafeInt32ToUintn (Operand, &Result);
36 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
37 }
38
39 TEST(ConversionTestSuite, TestSafeUint32ToIntn) {
40 RETURN_STATUS Status;
41 UINT32 Operand;
42 INTN Result;
43
44 //
45 // For x64, INTN is same as INT64 which is a superset of INT32
46 // This is just a cast then, and it'll never fail
47 //
48
49 //
50 // If Operand is non-negative, then it's a cast
51 //
52 Operand = 0xabababab;
53 Result = 0;
54 Status = SafeUint32ToIntn (Operand, &Result);
55 ASSERT_EQ (Status, RETURN_SUCCESS);
56 ASSERT_EQ (0xabababab, Result);
57 }
58
59 TEST(ConversionTestSuite, TestSafeIntnToInt32) {
60 RETURN_STATUS Status;
61 INTN Operand;
62 INT32 Result;
63
64 //
65 // If Operand is between MIN_INT32 and MAX_INT32 inclusive, then it's a cast
66 //
67 Operand = 0x5bababab;
68 Result = 0;
69 Status = SafeIntnToInt32 (Operand, &Result);
70 ASSERT_EQ (Status, RETURN_SUCCESS);
71 ASSERT_EQ (0x5bababab, Result);
72
73 Operand = (-1537977259);
74 Status = SafeIntnToInt32 (Operand, &Result);
75 ASSERT_EQ (Status, RETURN_SUCCESS);
76 ASSERT_EQ ((-1537977259), Result);
77
78 //
79 // Otherwise should result in an error status
80 //
81 Operand = (0x5babababefefefef);
82 Status = SafeIntnToInt32 (Operand, &Result);
83 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
84
85 Operand = (-6605562033422200815);
86 Status = SafeIntnToInt32 (Operand, &Result);
87 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
88 }
89
90 TEST(ConversionTestSuite, TestSafeIntnToUint32) {
91 RETURN_STATUS Status;
92 INTN Operand;
93 UINT32 Result;
94
95 //
96 // If Operand is between 0 and MAX_UINT32 inclusive, then it's a cast
97 //
98 Operand = 0xabababab;
99 Result = 0;
100 Status = SafeIntnToUint32 (Operand, &Result);
101 ASSERT_EQ (Status, RETURN_SUCCESS);
102 ASSERT_EQ (0xabababab, Result);
103
104 //
105 // Otherwise should result in an error status
106 //
107 Operand = (0x5babababefefefef);
108 Status = SafeIntnToUint32 (Operand, &Result);
109 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
110
111 Operand = (-6605562033422200815);
112 Status = SafeIntnToUint32 (Operand, &Result);
113 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
114 }
115
116 TEST(ConversionTestSuite, TestSafeUintnToUint32) {
117 RETURN_STATUS Status;
118 UINTN Operand;
119 UINT32 Result;
120
121 //
122 // If Operand is <= MAX_UINT32, then it's a cast
123 //
124 Operand = 0xabababab;
125 Result = 0;
126 Status = SafeUintnToUint32 (Operand, &Result);
127 ASSERT_EQ (Status, RETURN_SUCCESS);
128 ASSERT_EQ (0xabababab, Result);
129
130 //
131 // Otherwise should result in an error status
132 //
133 Operand = (0xababababefefefef);
134 Status = SafeUintnToUint32 (Operand, &Result);
135 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
136 }
137
138 TEST(ConversionTestSuite, TestSafeUintnToIntn) {
139 RETURN_STATUS Status;
140 UINTN Operand;
141 INTN Result;
142
143 //
144 // If Operand is <= MAX_INTN (0x7fff_ffff_ffff_ffff), then it's a cast
145 //
146 Operand = 0x5babababefefefef;
147 Result = 0;
148 Status = SafeUintnToIntn (Operand, &Result);
149 ASSERT_EQ (Status, RETURN_SUCCESS);
150 ASSERT_EQ (0x5babababefefefef, Result);
151
152 //
153 // Otherwise should result in an error status
154 //
155 Operand = (0xababababefefefef);
156 Status = SafeUintnToIntn (Operand, &Result);
157 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
158 }
159
160 TEST(ConversionTestSuite, TestSafeUintnToInt64) {
161 RETURN_STATUS Status;
162 UINTN Operand;
163 INT64 Result;
164
165 //
166 // If Operand is <= MAX_INT64, then it's a cast
167 //
168 Operand = 0x5babababefefefef;
169 Result = 0;
170 Status = SafeUintnToInt64 (Operand, &Result);
171 ASSERT_EQ (Status, RETURN_SUCCESS);
172 ASSERT_EQ (0x5babababefefefef, Result);
173
174 //
175 // Otherwise should result in an error status
176 //
177 Operand = (0xababababefefefef);
178 Status = SafeUintnToInt64 (Operand, &Result);
179 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
180 }
181
182 TEST(ConversionTestSuite, TestSafeInt64ToIntn) {
183 RETURN_STATUS Status;
184 INT64 Operand;
185 INTN Result;
186
187 //
188 // INTN is same as INT64 in x64, so this is just a cast
189 //
190 Operand = 0x5babababefefefef;
191 Result = 0;
192 Status = SafeInt64ToIntn (Operand, &Result);
193 ASSERT_EQ (Status, RETURN_SUCCESS);
194 ASSERT_EQ (0x5babababefefefef, Result);
195 }
196
197 TEST(ConversionTestSuite, TestSafeInt64ToUintn) {
198 RETURN_STATUS Status;
199 INT64 Operand;
200 UINTN Result;
201
202 //
203 // If Operand is non-negative, then it's a cast
204 //
205 Operand = 0x5babababefefefef;
206 Result = 0;
207 Status = SafeInt64ToUintn (Operand, &Result);
208 ASSERT_EQ (Status, RETURN_SUCCESS);
209 ASSERT_EQ ((UINTN)0x5babababefefefef, Result);
210
211 //
212 // Otherwise should result in an error status
213 //
214 Operand = (-6605562033422200815);
215 Status = SafeInt64ToUintn (Operand, &Result);
216 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
217 }
218
219 TEST(ConversionTestSuite, TestSafeUint64ToIntn) {
220 RETURN_STATUS Status;
221 UINT64 Operand;
222 INTN Result;
223
224 //
225 // If Operand is <= MAX_INTN (0x7fff_ffff_ffff_ffff), then it's a cast
226 //
227 Operand = 0x5babababefefefef;
228 Result = 0;
229 Status = SafeUint64ToIntn (Operand, &Result);
230 ASSERT_EQ (Status, RETURN_SUCCESS);
231 ASSERT_EQ (0x5babababefefefef, Result);
232
233 //
234 // Otherwise should result in an error status
235 //
236 Operand = (0xababababefefefef);
237 Status = SafeUint64ToIntn (Operand, &Result);
238 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
239 }
240
241 TEST(ConversionTestSuite, TestSafeUint64ToUintn) {
242 RETURN_STATUS Status;
243 UINT64 Operand;
244 UINTN Result;
245
246 //
247 // UINTN is same as UINT64 in x64, so this is just a cast
248 //
249 Operand = 0xababababefefefef;
250 Result = 0;
251 Status = SafeUint64ToUintn (Operand, &Result);
252 ASSERT_EQ (Status, RETURN_SUCCESS);
253 ASSERT_EQ (0xababababefefefef, Result);
254 }
255
256 TEST(AdditionSubtractionTestSuite, TestSafeUintnAdd) {
257 RETURN_STATUS Status;
258 UINTN Augend;
259 UINTN Addend;
260 UINTN Result;
261
262 //
263 // If the result of addition doesn't overflow MAX_UINTN, then it's addition
264 //
265 Augend = 0x3a3a3a3a12121212;
266 Addend = 0x3a3a3a3a12121212;
267 Result = 0;
268 Status = SafeUintnAdd (Augend, Addend, &Result);
269 ASSERT_EQ (Status, RETURN_SUCCESS);
270 ASSERT_EQ ((UINTN)0x7474747424242424, Result);
271
272 //
273 // Otherwise should result in an error status
274 //
275 Augend = 0xababababefefefef;
276 Addend = 0xbcbcbcbcdededede;
277 Status = SafeUintnAdd (Augend, Addend, &Result);
278 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
279 }
280
281 TEST(AdditionSubtractionTestSuite, TestSafeIntnAdd) {
282 RETURN_STATUS Status;
283 INTN Augend;
284 INTN Addend;
285 INTN Result;
286
287 //
288 // If the result of addition doesn't overflow MAX_INTN
289 // and doesn't underflow MIN_INTN, then it's addition
290 //
291 Augend = 0x3a3a3a3a3a3a3a3a;
292 Addend = 0x3a3a3a3a3a3a3a3a;
293 Result = 0;
294 Status = SafeIntnAdd (Augend, Addend, &Result);
295 ASSERT_EQ (Status, RETURN_SUCCESS);
296 ASSERT_EQ (0x7474747474747474, Result);
297
298 Augend = (-4195730024608447034);
299 Addend = (-4195730024608447034);
300 Status = SafeIntnAdd (Augend, Addend, &Result);
301 ASSERT_EQ (Status, RETURN_SUCCESS);
302 ASSERT_EQ ((-8391460049216894068), Result);
303
304 //
305 // Otherwise should result in an error status
306 //
307 Augend = 0x5a5a5a5a5a5a5a5a;
308 Addend = 0x5a5a5a5a5a5a5a5a;
309 Status = SafeIntnAdd (Augend, Addend, &Result);
310 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
311
312 Augend = (-6510615555426900570);
313 Addend = (-6510615555426900570);
314 Status = SafeIntnAdd (Augend, Addend, &Result);
315 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
316 }
317
318 TEST(AdditionSubtractionTestSuite, TestSafeUintnSub) {
319 RETURN_STATUS Status;
320 UINTN Minuend;
321 UINTN Subtrahend;
322 UINTN Result;
323
324 //
325 // If Minuend >= Subtrahend, then it's subtraction
326 //
327 Minuend = 0x5a5a5a5a5a5a5a5a;
328 Subtrahend = 0x3b3b3b3b3b3b3b3b;
329 Result = 0;
330 Status = SafeUintnSub (Minuend, Subtrahend, &Result);
331 ASSERT_EQ (Status, RETURN_SUCCESS);
332 ASSERT_EQ ((UINTN)0x1f1f1f1f1f1f1f1f, Result);
333
334 //
335 // Otherwise should result in an error status
336 //
337 Minuend = 0x5a5a5a5a5a5a5a5a;
338 Subtrahend = 0x6d6d6d6d6d6d6d6d;
339 Status = SafeUintnSub (Minuend, Subtrahend, &Result);
340 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
341 }
342
343 TEST(AdditionSubtractionTestSuite, TestSafeIntnSub) {
344 RETURN_STATUS Status;
345 INTN Minuend;
346 INTN Subtrahend;
347 INTN Result;
348
349 //
350 // If the result of subtractions doesn't overflow MAX_INTN or
351 // underflow MIN_INTN, then it's subtraction
352 //
353 Minuend = 0x5a5a5a5a5a5a5a5a;
354 Subtrahend = 0x3a3a3a3a3a3a3a3a;
355 Result = 0;
356 Status = SafeIntnSub (Minuend, Subtrahend, &Result);
357 ASSERT_EQ (Status, RETURN_SUCCESS);
358 ASSERT_EQ (0x2020202020202020, Result);
359
360 Minuend = 0x3a3a3a3a3a3a3a3a;
361 Subtrahend = 0x5a5a5a5a5a5a5a5a;
362 Status = SafeIntnSub (Minuend, Subtrahend, &Result);
363 ASSERT_EQ (Status, RETURN_SUCCESS);
364 ASSERT_EQ ((-2314885530818453536), Result);
365
366 //
367 // Otherwise should result in an error status
368 //
369 Minuend = (-8825501086245354106);
370 Subtrahend = 8825501086245354106;
371 Status = SafeIntnSub (Minuend, Subtrahend, &Result);
372 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
373
374 Minuend = (8825501086245354106);
375 Subtrahend = (-8825501086245354106);
376 Status = SafeIntnSub (Minuend, Subtrahend, &Result);
377 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
378 }
379
380 TEST(MultiplicationTestSuite, TestSafeUintnMult) {
381 RETURN_STATUS Status;
382 UINTN Multiplicand;
383 UINTN Multiplier;
384 UINTN Result;
385
386 //
387 // If the result of multiplication doesn't overflow MAX_UINTN, it will succeed
388 //
389 Multiplicand = 0x123456789a;
390 Multiplier = 0x1234567;
391 Result = 0;
392 Status = SafeUintnMult (Multiplicand, Multiplier, &Result);
393 ASSERT_EQ (Status, RETURN_SUCCESS);
394 ASSERT_EQ ((UINTN)0x14b66db9745a07f6, Result);
395
396 //
397 // Otherwise should result in an error status
398 //
399 Multiplicand = 0x123456789a;
400 Multiplier = 0x12345678;
401 Status = SafeUintnMult (Multiplicand, Multiplier, &Result);
402 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
403 }
404
405 TEST(MultiplicationTestSuite, TestSafeIntnMult) {
406 RETURN_STATUS Status;
407 INTN Multiplicand;
408 INTN Multiplier;
409 INTN Result;
410
411 //
412 // If the result of multiplication doesn't overflow MAX_INTN and doesn't
413 // underflow MIN_UINTN, it will succeed
414 //
415 Multiplicand = 0x123456789;
416 Multiplier = 0x6789abcd;
417 Result = 0;
418 Status = SafeIntnMult (Multiplicand, Multiplier, &Result);
419 ASSERT_EQ (Status, RETURN_SUCCESS);
420 ASSERT_EQ (0x75cd9045220d6bb5, Result);
421
422 //
423 // Otherwise should result in an error status
424 //
425 Multiplicand = 0x123456789;
426 Multiplier = 0xa789abcd;
427 Status = SafeIntnMult (Multiplicand, Multiplier, &Result);
428 ASSERT_EQ (RETURN_BUFFER_TOO_SMALL, Status);
429 }