2 This library provides helper functions to prevent integer overflow during
3 type conversion, addition, subtraction, and multiplication.
5 Copyright (c) 2017, Microsoft Corporation
8 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include <Library/SafeIntLib.h>
16 INT32 -> UINTN conversion
18 Converts the value specified by Operand to a value specified by Result type
19 and stores the converted value into the caller allocated output buffer
20 specified by Result. The caller must pass in a Result buffer that is at
21 least as large as the Result type.
23 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
25 If the conversion results in an overflow or an underflow condition, then
26 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
28 @param[in] Operand Operand to be converted to new type
29 @param[out] Result Pointer to the result of conversion
31 @retval RETURN_SUCCESS Successful conversion
32 @retval RETURN_BUFFER_TOO_SMALL Overflow
33 @retval RETURN_INVALID_PARAMETER Result is NULL
42 if (sizeof (UINTN
) == sizeof (UINT32
)) {
43 return SafeInt32ToUint32 (Operand
, (UINT32
*)Result
);
46 return SafeInt32ToUint64 (Operand
, (UINT64
*)Result
);
50 UINT32 -> INTN conversion
52 Converts the value specified by Operand to a value specified by Result type
53 and stores the converted value into the caller allocated output buffer
54 specified by Result. The caller must pass in a Result buffer that is at
55 least as large as the Result type.
57 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
59 If the conversion results in an overflow or an underflow condition, then
60 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
62 @param[in] Operand Operand to be converted to new type
63 @param[out] Result Pointer to the result of conversion
65 @retval RETURN_SUCCESS Successful conversion
66 @retval RETURN_BUFFER_TOO_SMALL Overflow
67 @retval RETURN_INVALID_PARAMETER Result is NULL
77 return RETURN_INVALID_PARAMETER
;
80 if (sizeof (UINTN
) == sizeof (UINT32
)) {
81 return SafeUint32ToInt32 (Operand
, (INT32
*)Result
);
85 return RETURN_SUCCESS
;
89 INTN -> INT32 conversion
91 Converts the value specified by Operand to a value specified by Result type
92 and stores the converted value into the caller allocated output buffer
93 specified by Result. The caller must pass in a Result buffer that is at
94 least as large as the Result type.
96 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
98 If the conversion results in an overflow or an underflow condition, then
99 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
101 @param[in] Operand Operand to be converted to new type
102 @param[out] Result Pointer to the result of conversion
104 @retval RETURN_SUCCESS Successful conversion
105 @retval RETURN_BUFFER_TOO_SMALL Overflow
106 @retval RETURN_INVALID_PARAMETER Result is NULL
115 if (Result
== NULL
) {
116 return RETURN_INVALID_PARAMETER
;
119 if (sizeof (UINTN
) == sizeof (UINT32
)) {
120 *Result
= (INT32
)Operand
;
121 return RETURN_SUCCESS
;
124 return SafeInt64ToInt32 ((INT64
)Operand
, Result
);
128 INTN -> UINT32 conversion
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.
135 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
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.
140 @param[in] Operand Operand to be converted to new type
141 @param[out] Result Pointer to the result of conversion
143 @retval RETURN_SUCCESS Successful conversion
144 @retval RETURN_BUFFER_TOO_SMALL Overflow
145 @retval RETURN_INVALID_PARAMETER Result is NULL
154 RETURN_STATUS Status
;
156 if (Result
== NULL
) {
157 return RETURN_INVALID_PARAMETER
;
160 if (sizeof (UINTN
) == sizeof (UINT32
)) {
162 *Result
= (UINT32
)Operand
;
163 Status
= RETURN_SUCCESS
;
165 *Result
= UINT32_ERROR
;
166 Status
= RETURN_BUFFER_TOO_SMALL
;
172 return SafeInt64ToUint32 ((INT64
)Operand
, Result
);
176 UINTN -> UINT32 conversion
178 Converts the value specified by Operand to a value specified by Result type
179 and stores the converted value into the caller allocated output buffer
180 specified by Result. The caller must pass in a Result buffer that is at
181 least as large as the Result type.
183 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
185 If the conversion results in an overflow or an underflow condition, then
186 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
188 @param[in] Operand Operand to be converted to new type
189 @param[out] Result Pointer to the result of conversion
191 @retval RETURN_SUCCESS Successful conversion
192 @retval RETURN_BUFFER_TOO_SMALL Overflow
193 @retval RETURN_INVALID_PARAMETER Result is NULL
202 if (Result
== NULL
) {
203 return RETURN_INVALID_PARAMETER
;
206 if (sizeof (UINTN
) == sizeof (UINT32
)) {
207 *Result
= (UINT32
)Operand
;
208 return RETURN_SUCCESS
;
211 return SafeUint64ToUint32 ((UINT64
)Operand
, Result
);
215 UINTN -> INT64 conversion
217 Converts the value specified by Operand to a value specified by Result type
218 and stores the converted value into the caller allocated output buffer
219 specified by Result. The caller must pass in a Result buffer that is at
220 least as large as the Result type.
222 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
224 If the conversion results in an overflow or an underflow condition, then
225 Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
227 @param[in] Operand Operand to be converted to new type
228 @param[out] Result Pointer to the result of conversion
230 @retval RETURN_SUCCESS Successful conversion
231 @retval RETURN_BUFFER_TOO_SMALL Overflow
232 @retval RETURN_INVALID_PARAMETER Result is NULL
241 if (Result
== NULL
) {
242 return RETURN_INVALID_PARAMETER
;
245 if (sizeof (UINTN
) == sizeof (UINT32
)) {
246 *Result
= (INT64
)Operand
;
247 return RETURN_SUCCESS
;
250 return SafeUint64ToInt64 ((UINT64
)Operand
, Result
);
254 INT64 -> INTN conversion
256 Converts the value specified by Operand to a value specified by Result type
257 and stores the converted value into the caller allocated output buffer
258 specified by Result. The caller must pass in a Result buffer that is at
259 least as large as the Result type.
261 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
263 If the conversion results in an overflow or an underflow condition, then
264 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
266 @param[in] Operand Operand to be converted to new type
267 @param[out] Result Pointer to the result of conversion
269 @retval RETURN_SUCCESS Successful conversion
270 @retval RETURN_BUFFER_TOO_SMALL Overflow
271 @retval RETURN_INVALID_PARAMETER Result is NULL
280 if (Result
== NULL
) {
281 return RETURN_INVALID_PARAMETER
;
284 if (sizeof (UINTN
) == sizeof (UINT32
)) {
285 return SafeInt64ToInt32 (Operand
, (INT32
*)Result
);
288 *Result
= (INTN
)Operand
;
289 return RETURN_SUCCESS
;
293 INT64 -> UINTN conversion
295 Converts the value specified by Operand to a value specified by Result type
296 and stores the converted value into the caller allocated output buffer
297 specified by Result. The caller must pass in a Result buffer that is at
298 least as large as the Result type.
300 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
302 If the conversion results in an overflow or an underflow condition, then
303 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
305 @param[in] Operand Operand to be converted to new type
306 @param[out] Result Pointer to the result of conversion
308 @retval RETURN_SUCCESS Successful conversion
309 @retval RETURN_BUFFER_TOO_SMALL Overflow
310 @retval RETURN_INVALID_PARAMETER Result is NULL
319 if (sizeof (UINTN
) == sizeof (UINT32
)) {
320 return SafeInt64ToUint32 (Operand
, (UINT32
*)Result
);
323 return SafeInt64ToUint64 (Operand
, (UINT64
*)Result
);
327 UINT64 -> UINTN conversion
329 Converts the value specified by Operand to a value specified by Result type
330 and stores the converted value into the caller allocated output buffer
331 specified by Result. The caller must pass in a Result buffer that is at
332 least as large as the Result type.
334 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
336 If the conversion results in an overflow or an underflow condition, then
337 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
339 @param[in] Operand Operand to be converted to new type
340 @param[out] Result Pointer to the result of conversion
342 @retval RETURN_SUCCESS Successful conversion
343 @retval RETURN_BUFFER_TOO_SMALL Overflow
344 @retval RETURN_INVALID_PARAMETER Result is NULL
353 if (Result
== NULL
) {
354 return RETURN_INVALID_PARAMETER
;
357 if (sizeof (UINTN
) == sizeof (UINT32
)) {
358 return SafeUint64ToUint32 ((UINT64
)Operand
, (UINT32
*)Result
);
362 return RETURN_SUCCESS
;
368 Performs the requested operation using the input parameters into a value
369 specified by Result type and stores the converted value into the caller
370 allocated output buffer specified by Result. The caller must pass in a
371 Result buffer that is at least as large as the Result type.
373 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
375 If the requested operation results in an overflow or an underflow condition,
376 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
378 @param[in] Augend A number to which addend will be added
379 @param[in] Addend A number to be added to another
380 @param[out] Result Pointer to the result of addition
382 @retval RETURN_SUCCESS Successful addition
383 @retval RETURN_BUFFER_TOO_SMALL Overflow
384 @retval RETURN_INVALID_PARAMETER Result is NULL
394 RETURN_STATUS Status
;
396 if (Result
== NULL
) {
397 return RETURN_INVALID_PARAMETER
;
400 if (sizeof (UINTN
) == sizeof (UINT32
)) {
401 if ((UINT32
)(Augend
+ Addend
) >= Augend
) {
402 *Result
= (Augend
+ Addend
);
403 Status
= RETURN_SUCCESS
;
405 *Result
= UINTN_ERROR
;
406 Status
= RETURN_BUFFER_TOO_SMALL
;
412 return SafeUint64Add ((UINT64
)Augend
, (UINT64
)Addend
, (UINT64
*)Result
);
418 Performs the requested operation using the input parameters into a value
419 specified by Result type and stores the converted value into the caller
420 allocated output buffer specified by Result. The caller must pass in a
421 Result buffer that is at least as large as the Result type.
423 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
425 If the requested operation results in an overflow or an underflow condition,
426 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
428 @param[in] Minuend A number from which another is to be subtracted.
429 @param[in] Subtrahend A number to be subtracted from another
430 @param[out] Result Pointer to the result of subtraction
432 @retval RETURN_SUCCESS Successful subtraction
433 @retval RETURN_BUFFER_TOO_SMALL Underflow
434 @retval RETURN_INVALID_PARAMETER Result is NULL
444 RETURN_STATUS Status
;
446 if (Result
== NULL
) {
447 return RETURN_INVALID_PARAMETER
;
450 if (sizeof (UINTN
) == sizeof (UINT32
)) {
451 if (Minuend
>= Subtrahend
) {
452 *Result
= (Minuend
- Subtrahend
);
453 Status
= RETURN_SUCCESS
;
455 *Result
= UINTN_ERROR
;
456 Status
= RETURN_BUFFER_TOO_SMALL
;
462 return SafeUint64Sub ((UINT64
)Minuend
, (UINT64
)Subtrahend
, (UINT64
*)Result
);
468 Performs the requested operation using the input parameters into a value
469 specified by Result type and stores the converted value into the caller
470 allocated output buffer specified by Result. The caller must pass in a
471 Result buffer that is at least as large as the Result type.
473 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
475 If the requested operation results in an overflow or an underflow condition,
476 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
478 @param[in] Multiplicand A number that is to be multiplied by another
479 @param[in] Multiplier A number by which the multiplicand is to be multiplied
480 @param[out] Result Pointer to the result of multiplication
482 @retval RETURN_SUCCESS Successful multiplication
483 @retval RETURN_BUFFER_TOO_SMALL Overflow
484 @retval RETURN_INVALID_PARAMETER Result is NULL
489 IN UINTN Multiplicand
,
494 UINT64 IntermediateResult
;
496 if (sizeof (UINTN
) == sizeof (UINT32
)) {
497 IntermediateResult
= ((UINT64
)Multiplicand
) *((UINT64
)Multiplier
);
499 return SafeUint64ToUintn (IntermediateResult
, Result
);
502 return SafeUint64Mult ((UINT64
)Multiplicand
, (UINT64
)Multiplier
, (UINT64
*)Result
);
508 Performs the requested operation using the input parameters into a value
509 specified by Result type and stores the converted value into the caller
510 allocated output buffer specified by Result. The caller must pass in a
511 Result buffer that is at least as large as the Result type.
513 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
515 If the requested operation results in an overflow or an underflow condition,
516 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
518 @param[in] Augend A number to which addend will be added
519 @param[in] Addend A number to be added to another
520 @param[out] Result Pointer to the result of addition
522 @retval RETURN_SUCCESS Successful addition
523 @retval RETURN_BUFFER_TOO_SMALL Overflow
524 @retval RETURN_INVALID_PARAMETER Result is NULL
534 if (sizeof (UINTN
) == sizeof (UINT32
)) {
535 return SafeInt64ToIntn (((INT64
)Augend
) + ((INT64
)Addend
), Result
);
538 return SafeInt64Add ((INT64
)Augend
, (INT64
)Addend
, (INT64
*)Result
);
544 Performs the requested operation using the input parameters into a value
545 specified by Result type and stores the converted value into the caller
546 allocated output buffer specified by Result. The caller must pass in a
547 Result buffer that is at least as large as the Result type.
549 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
551 If the requested operation results in an overflow or an underflow condition,
552 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
554 @param[in] Minuend A number from which another is to be subtracted.
555 @param[in] Subtrahend A number to be subtracted from another
556 @param[out] Result Pointer to the result of subtraction
558 @retval RETURN_SUCCESS Successful subtraction
559 @retval RETURN_BUFFER_TOO_SMALL Underflow
560 @retval RETURN_INVALID_PARAMETER Result is NULL
570 if (sizeof (UINTN
) == sizeof (UINT32
)) {
571 return SafeInt64ToIntn (((INT64
)Minuend
) - ((INT64
)Subtrahend
), Result
);
574 return SafeInt64Sub ((INT64
)Minuend
, (INT64
)Subtrahend
, (INT64
*)Result
);
580 Performs the requested operation using the input parameters into a value
581 specified by Result type and stores the converted value into the caller
582 allocated output buffer specified by Result. The caller must pass in a
583 Result buffer that is at least as large as the Result type.
585 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
587 If the requested operation results in an overflow or an underflow condition,
588 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
590 @param[in] Multiplicand A number that is to be multiplied by another
591 @param[in] Multiplier A number by which the multiplicand is to be multiplied
592 @param[out] Result Pointer to the result of multiplication
594 @retval RETURN_SUCCESS Successful multiplication
595 @retval RETURN_BUFFER_TOO_SMALL Overflow
596 @retval RETURN_INVALID_PARAMETER Result is NULL
601 IN INTN Multiplicand
,
606 if (sizeof (UINTN
) == sizeof (UINT32
)) {
607 return SafeInt64ToIntn (((INT64
)Multiplicand
) *((INT64
)Multiplier
), Result
);
610 return SafeInt64Mult ((INT64
)Multiplicand
, (INT64
)Multiplier
, (INT64
*)Result
);