]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseSafeIntLib/SafeIntLib64.c
MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
[mirror_edk2.git] / MdePkg / Library / BaseSafeIntLib / SafeIntLib64.c
1 /** @file
2 This library provides helper functions to prevent integer overflow during
3 type conversion, addition, subtraction, and multiplication.
4
5 Copyright (c) 2017, Microsoft Corporation
6
7 All rights reserved.
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10 1. Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 **/
28
29 #include <Base.h>
30 #include <Library/SafeIntLib.h>
31
32 /**
33 INT32 -> UINTN conversion
34
35 Converts the value specified by Operand to a value specified by Result type
36 and stores the converted value into the caller allocated output buffer
37 specified by Result. The caller must pass in a Result buffer that is at
38 least as large as the Result type.
39
40 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
41
42 If the conversion results in an overflow or an underflow condition, then
43 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
44
45 @param[in] Operand Operand to be converted to new type
46 @param[out] Result Pointer to the result of conversion
47
48 @retval RETURN_SUCCESS Successful conversion
49 @retval RETURN_BUFFER_TOO_SMALL Overflow
50 @retval RETURN_INVALID_PARAMETER Result is NULL
51 **/
52 RETURN_STATUS
53 EFIAPI
54 SafeInt32ToUintn (
55 IN INT32 Operand,
56 OUT UINTN *Result
57 )
58 {
59 return SafeInt32ToUint64 (Operand, (UINT64 *) Result);
60 }
61
62 /**
63 UINT32 -> INTN conversion
64
65 Converts the value specified by Operand to a value specified by Result type
66 and stores the converted value into the caller allocated output buffer
67 specified by Result. The caller must pass in a Result buffer that is at
68 least as large as the Result type.
69
70 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
71
72 If the conversion results in an overflow or an underflow condition, then
73 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
74
75 @param[in] Operand Operand to be converted to new type
76 @param[out] Result Pointer to the result of conversion
77
78 @retval RETURN_SUCCESS Successful conversion
79 @retval RETURN_BUFFER_TOO_SMALL Overflow
80 @retval RETURN_INVALID_PARAMETER Result is NULL
81 **/
82 RETURN_STATUS
83 EFIAPI
84 SafeUint32ToIntn (
85 IN UINT32 Operand,
86 OUT INTN *Result
87 )
88 {
89 if (Result == NULL) {
90 return RETURN_INVALID_PARAMETER;
91 }
92
93 *Result = Operand;
94 return RETURN_SUCCESS;
95 }
96
97 /**
98 INTN -> INT32 conversion
99
100 Converts the value specified by Operand to a value specified by Result type
101 and stores the converted value into the caller allocated output buffer
102 specified by Result. The caller must pass in a Result buffer that is at
103 least as large as the Result type.
104
105 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
106
107 If the conversion results in an overflow or an underflow condition, then
108 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
109
110 @param[in] Operand Operand to be converted to new type
111 @param[out] Result Pointer to the result of conversion
112
113 @retval RETURN_SUCCESS Successful conversion
114 @retval RETURN_BUFFER_TOO_SMALL Overflow
115 @retval RETURN_INVALID_PARAMETER Result is NULL
116 **/
117 RETURN_STATUS
118 EFIAPI
119 SafeIntnToInt32 (
120 IN INTN Operand,
121 OUT INT32 *Result
122 )
123 {
124 return SafeInt64ToInt32 ((INT64) Operand, Result);
125 }
126
127 /**
128 INTN -> UINT32 conversion
129
130 Converts the value specified by Operand to a value specified by Result type
131 and stores the converted value into the caller allocated output buffer
132 specified by Result. The caller must pass in a Result buffer that is at
133 least as large as the Result type.
134
135 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
136
137 If the conversion results in an overflow or an underflow condition, then
138 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
139
140 @param[in] Operand Operand to be converted to new type
141 @param[out] Result Pointer to the result of conversion
142
143 @retval RETURN_SUCCESS Successful conversion
144 @retval RETURN_BUFFER_TOO_SMALL Overflow
145 @retval RETURN_INVALID_PARAMETER Result is NULL
146 **/
147 RETURN_STATUS
148 EFIAPI
149 SafeIntnToUint32 (
150 IN INTN Operand,
151 OUT UINT32 *Result
152 )
153 {
154 return SafeInt64ToUint32 ((INT64)Operand, Result);
155 }
156
157 /**
158 UINTN -> UINT32 conversion
159
160 Converts the value specified by Operand to a value specified by Result type
161 and stores the converted value into the caller allocated output buffer
162 specified by Result. The caller must pass in a Result buffer that is at
163 least as large as the Result type.
164
165 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
166
167 If the conversion results in an overflow or an underflow condition, then
168 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
169
170 @param[in] Operand Operand to be converted to new type
171 @param[out] Result Pointer to the result of conversion
172
173 @retval RETURN_SUCCESS Successful conversion
174 @retval RETURN_BUFFER_TOO_SMALL Overflow
175 @retval RETURN_INVALID_PARAMETER Result is NULL
176 **/
177 RETURN_STATUS
178 EFIAPI
179 SafeUintnToUint32 (
180 IN UINTN Operand,
181 OUT UINT32 *Result
182 )
183 {
184 return SafeUint64ToUint32 ((UINT64)Operand, Result);
185 }
186
187 /**
188 UINTN -> INT64 conversion
189
190 Converts the value specified by Operand to a value specified by Result type
191 and stores the converted value into the caller allocated output buffer
192 specified by Result. The caller must pass in a Result buffer that is at
193 least as large as the Result type.
194
195 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
196
197 If the conversion results in an overflow or an underflow condition, then
198 Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
199
200 @param[in] Operand Operand to be converted to new type
201 @param[out] Result Pointer to the result of conversion
202
203 @retval RETURN_SUCCESS Successful conversion
204 @retval RETURN_BUFFER_TOO_SMALL Overflow
205 @retval RETURN_INVALID_PARAMETER Result is NULL
206 **/
207 RETURN_STATUS
208 EFIAPI
209 SafeUintnToInt64 (
210 IN UINTN Operand,
211 OUT INT64 *Result
212 )
213 {
214 return SafeUint64ToInt64 ((UINT64)Operand, Result);
215 }
216
217 /**
218 INT64 -> INTN conversion
219
220 Converts the value specified by Operand to a value specified by Result type
221 and stores the converted value into the caller allocated output buffer
222 specified by Result. The caller must pass in a Result buffer that is at
223 least as large as the Result type.
224
225 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
226
227 If the conversion results in an overflow or an underflow condition, then
228 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
229
230 @param[in] Operand Operand to be converted to new type
231 @param[out] Result Pointer to the result of conversion
232
233 @retval RETURN_SUCCESS Successful conversion
234 @retval RETURN_BUFFER_TOO_SMALL Overflow
235 @retval RETURN_INVALID_PARAMETER Result is NULL
236 **/
237 RETURN_STATUS
238 EFIAPI
239 SafeInt64ToIntn (
240 IN INT64 Operand,
241 OUT INTN *Result
242 )
243 {
244 if (Result == NULL) {
245 return RETURN_INVALID_PARAMETER;
246 }
247
248 *Result = (INTN)Operand;
249 return RETURN_SUCCESS;
250 }
251
252 /**
253 INT64 -> UINTN conversion
254
255 Converts the value specified by Operand to a value specified by Result type
256 and stores the converted value into the caller allocated output buffer
257 specified by Result. The caller must pass in a Result buffer that is at
258 least as large as the Result type.
259
260 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
261
262 If the conversion results in an overflow or an underflow condition, then
263 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
264
265 @param[in] Operand Operand to be converted to new type
266 @param[out] Result Pointer to the result of conversion
267
268 @retval RETURN_SUCCESS Successful conversion
269 @retval RETURN_BUFFER_TOO_SMALL Overflow
270 @retval RETURN_INVALID_PARAMETER Result is NULL
271 **/
272 RETURN_STATUS
273 EFIAPI
274 SafeInt64ToUintn (
275 IN INT64 Operand,
276 OUT UINTN *Result
277 )
278 {
279 return SafeInt64ToUint64 (Operand, (UINT64 *)Result);
280 }
281
282 /**
283 UINT64 -> UINTN conversion
284
285 Converts the value specified by Operand to a value specified by Result type
286 and stores the converted value into the caller allocated output buffer
287 specified by Result. The caller must pass in a Result buffer that is at
288 least as large as the Result type.
289
290 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
291
292 If the conversion results in an overflow or an underflow condition, then
293 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
294
295 @param[in] Operand Operand to be converted to new type
296 @param[out] Result Pointer to the result of conversion
297
298 @retval RETURN_SUCCESS Successful conversion
299 @retval RETURN_BUFFER_TOO_SMALL Overflow
300 @retval RETURN_INVALID_PARAMETER Result is NULL
301 **/
302 RETURN_STATUS
303 EFIAPI
304 SafeUint64ToUintn (
305 IN UINT64 Operand,
306 OUT UINTN *Result
307 )
308 {
309 if (Result == NULL) {
310 return RETURN_INVALID_PARAMETER;
311 }
312
313 *Result = Operand;
314 return RETURN_SUCCESS;
315 }
316
317 /**
318 UINTN addition
319
320 Performs the requested operation using the input parameters into a value
321 specified by Result type and stores the converted value into the caller
322 allocated output buffer specified by Result. The caller must pass in a
323 Result buffer that is at least as large as the Result type.
324
325 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
326
327 If the requested operation results in an overflow or an underflow condition,
328 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
329
330 @param[in] Augend A number to which addend will be added
331 @param[in] Addend A number to be added to another
332 @param[out] Result Pointer to the result of addition
333
334 @retval RETURN_SUCCESS Successful addition
335 @retval RETURN_BUFFER_TOO_SMALL Overflow
336 @retval RETURN_INVALID_PARAMETER Result is NULL
337 **/
338 RETURN_STATUS
339 EFIAPI
340 SafeUintnAdd (
341 IN UINTN Augend,
342 IN UINTN Addend,
343 OUT UINTN *Result
344 )
345 {
346 return SafeUint64Add ((UINT64)Augend, (UINT64)Addend, (UINT64 *)Result);
347 }
348
349 /**
350 UINTN subtraction
351
352 Performs the requested operation using the input parameters into a value
353 specified by Result type and stores the converted value into the caller
354 allocated output buffer specified by Result. The caller must pass in a
355 Result buffer that is at least as large as the Result type.
356
357 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
358
359 If the requested operation results in an overflow or an underflow condition,
360 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
361
362 @param[in] Minuend A number from which another is to be subtracted.
363 @param[in] Subtrahend A number to be subtracted from another
364 @param[out] Result Pointer to the result of subtraction
365
366 @retval RETURN_SUCCESS Successful subtraction
367 @retval RETURN_BUFFER_TOO_SMALL Underflow
368 @retval RETURN_INVALID_PARAMETER Result is NULL
369 **/
370 RETURN_STATUS
371 EFIAPI
372 SafeUintnSub (
373 IN UINTN Minuend,
374 IN UINTN Subtrahend,
375 OUT UINTN *Result
376 )
377 {
378 return SafeUint64Sub ((UINT64)Minuend, (UINT64)Subtrahend, (UINT64 *)Result);
379 }
380
381 /**
382 UINTN multiplication
383
384 Performs the requested operation using the input parameters into a value
385 specified by Result type and stores the converted value into the caller
386 allocated output buffer specified by Result. The caller must pass in a
387 Result buffer that is at least as large as the Result type.
388
389 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
390
391 If the requested operation results in an overflow or an underflow condition,
392 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
393
394 @param[in] Multiplicand A number that is to be multiplied by another
395 @param[in] Multiplier A number by which the multiplicand is to be multiplied
396 @param[out] Result Pointer to the result of multiplication
397
398 @retval RETURN_SUCCESS Successful multiplication
399 @retval RETURN_BUFFER_TOO_SMALL Overflow
400 @retval RETURN_INVALID_PARAMETER Result is NULL
401 **/
402 RETURN_STATUS
403 EFIAPI
404 SafeUintnMult (
405 IN UINTN Multiplicand,
406 IN UINTN Multiplier,
407 OUT UINTN *Result
408 )
409 {
410 return SafeUint64Mult ((UINT64)Multiplicand, (UINT64)Multiplier, (UINT64 *)Result);
411 }
412
413 /**
414 INTN Addition
415
416 Performs the requested operation using the input parameters into a value
417 specified by Result type and stores the converted value into the caller
418 allocated output buffer specified by Result. The caller must pass in a
419 Result buffer that is at least as large as the Result type.
420
421 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
422
423 If the requested operation results in an overflow or an underflow condition,
424 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
425
426 @param[in] Augend A number to which addend will be added
427 @param[in] Addend A number to be added to another
428 @param[out] Result Pointer to the result of addition
429
430 @retval RETURN_SUCCESS Successful addition
431 @retval RETURN_BUFFER_TOO_SMALL Overflow
432 @retval RETURN_INVALID_PARAMETER Result is NULL
433 **/
434 RETURN_STATUS
435 EFIAPI
436 SafeIntnAdd (
437 IN INTN Augend,
438 IN INTN Addend,
439 OUT INTN *Result
440 )
441 {
442 return SafeInt64Add ((INT64)Augend, (INT64)Addend, (INT64 *)Result);
443 }
444
445 /**
446 INTN Subtraction
447
448 Performs the requested operation using the input parameters into a value
449 specified by Result type and stores the converted value into the caller
450 allocated output buffer specified by Result. The caller must pass in a
451 Result buffer that is at least as large as the Result type.
452
453 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
454
455 If the requested operation results in an overflow or an underflow condition,
456 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
457
458 @param[in] Minuend A number from which another is to be subtracted.
459 @param[in] Subtrahend A number to be subtracted from another
460 @param[out] Result Pointer to the result of subtraction
461
462 @retval RETURN_SUCCESS Successful subtraction
463 @retval RETURN_BUFFER_TOO_SMALL Underflow
464 @retval RETURN_INVALID_PARAMETER Result is NULL
465 **/
466 RETURN_STATUS
467 EFIAPI
468 SafeIntnSub (
469 IN INTN Minuend,
470 IN INTN Subtrahend,
471 OUT INTN *Result
472 )
473 {
474 return SafeInt64Sub ((INT64)Minuend, (INT64)Subtrahend, (INT64 *)Result);
475 }
476
477 /**
478 INTN multiplication
479
480 Performs the requested operation using the input parameters into a value
481 specified by Result type and stores the converted value into the caller
482 allocated output buffer specified by Result. The caller must pass in a
483 Result buffer that is at least as large as the Result type.
484
485 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
486
487 If the requested operation results in an overflow or an underflow condition,
488 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
489
490 @param[in] Multiplicand A number that is to be multiplied by another
491 @param[in] Multiplier A number by which the multiplicand is to be multiplied
492 @param[out] Result Pointer to the result of multiplication
493
494 @retval RETURN_SUCCESS Successful multiplication
495 @retval RETURN_BUFFER_TOO_SMALL Overflow
496 @retval RETURN_INVALID_PARAMETER Result is NULL
497 **/
498 RETURN_STATUS
499 EFIAPI
500 SafeIntnMult (
501 IN INTN Multiplicand,
502 IN INTN Multiplier,
503 OUT INTN *Result
504 )
505 {
506 return SafeInt64Mult ((INT64)Multiplicand, (INT64)Multiplier, (INT64 *)Result);
507 }
508