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
);
45 return SafeInt32ToUint64 (Operand
, (UINT64
*) Result
);
49 UINT32 -> INTN conversion
51 Converts the value specified by Operand to a value specified by Result type
52 and stores the converted value into the caller allocated output buffer
53 specified by Result. The caller must pass in a Result buffer that is at
54 least as large as the Result type.
56 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
58 If the conversion results in an overflow or an underflow condition, then
59 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
61 @param[in] Operand Operand to be converted to new type
62 @param[out] Result Pointer to the result of conversion
64 @retval RETURN_SUCCESS Successful conversion
65 @retval RETURN_BUFFER_TOO_SMALL Overflow
66 @retval RETURN_INVALID_PARAMETER Result is NULL
76 return RETURN_INVALID_PARAMETER
;
79 if (sizeof (UINTN
) == sizeof (UINT32
)) {
80 return SafeUint32ToInt32 (Operand
, (INT32
*)Result
);
83 return RETURN_SUCCESS
;
87 INTN -> INT32 conversion
89 Converts the value specified by Operand to a value specified by Result type
90 and stores the converted value into the caller allocated output buffer
91 specified by Result. The caller must pass in a Result buffer that is at
92 least as large as the Result type.
94 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
96 If the conversion results in an overflow or an underflow condition, then
97 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
99 @param[in] Operand Operand to be converted to new type
100 @param[out] Result Pointer to the result of conversion
102 @retval RETURN_SUCCESS Successful conversion
103 @retval RETURN_BUFFER_TOO_SMALL Overflow
104 @retval RETURN_INVALID_PARAMETER Result is NULL
113 if (Result
== NULL
) {
114 return RETURN_INVALID_PARAMETER
;
117 if (sizeof (UINTN
) == sizeof (UINT32
)) {
118 *Result
= (INT32
)Operand
;
119 return RETURN_SUCCESS
;
121 return SafeInt64ToInt32 ((INT64
) Operand
, Result
);
125 INTN -> UINT32 conversion
127 Converts the value specified by Operand to a value specified by Result type
128 and stores the converted value into the caller allocated output buffer
129 specified by Result. The caller must pass in a Result buffer that is at
130 least as large as the Result type.
132 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
134 If the conversion results in an overflow or an underflow condition, then
135 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
137 @param[in] Operand Operand to be converted to new type
138 @param[out] Result Pointer to the result of conversion
140 @retval RETURN_SUCCESS Successful conversion
141 @retval RETURN_BUFFER_TOO_SMALL Overflow
142 @retval RETURN_INVALID_PARAMETER Result is NULL
151 RETURN_STATUS Status
;
153 if (Result
== NULL
) {
154 return RETURN_INVALID_PARAMETER
;
157 if (sizeof (UINTN
) == sizeof (UINT32
)) {
159 *Result
= (UINT32
)Operand
;
160 Status
= RETURN_SUCCESS
;
162 *Result
= UINT32_ERROR
;
163 Status
= RETURN_BUFFER_TOO_SMALL
;
168 return SafeInt64ToUint32 ((INT64
)Operand
, Result
);
172 UINTN -> UINT32 conversion
174 Converts the value specified by Operand to a value specified by Result type
175 and stores the converted value into the caller allocated output buffer
176 specified by Result. The caller must pass in a Result buffer that is at
177 least as large as the Result type.
179 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
181 If the conversion results in an overflow or an underflow condition, then
182 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
184 @param[in] Operand Operand to be converted to new type
185 @param[out] Result Pointer to the result of conversion
187 @retval RETURN_SUCCESS Successful conversion
188 @retval RETURN_BUFFER_TOO_SMALL Overflow
189 @retval RETURN_INVALID_PARAMETER Result is NULL
198 if (Result
== NULL
) {
199 return RETURN_INVALID_PARAMETER
;
202 if (sizeof (UINTN
) == sizeof (UINT32
)) {
203 *Result
= (UINT32
)Operand
;
204 return RETURN_SUCCESS
;
206 return SafeUint64ToUint32 ((UINT64
)Operand
, Result
);
210 UINTN -> INT64 conversion
212 Converts the value specified by Operand to a value specified by Result type
213 and stores the converted value into the caller allocated output buffer
214 specified by Result. The caller must pass in a Result buffer that is at
215 least as large as the Result type.
217 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
219 If the conversion results in an overflow or an underflow condition, then
220 Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
222 @param[in] Operand Operand to be converted to new type
223 @param[out] Result Pointer to the result of conversion
225 @retval RETURN_SUCCESS Successful conversion
226 @retval RETURN_BUFFER_TOO_SMALL Overflow
227 @retval RETURN_INVALID_PARAMETER Result is NULL
236 if (Result
== NULL
) {
237 return RETURN_INVALID_PARAMETER
;
240 if (sizeof (UINTN
) == sizeof (UINT32
)) {
241 *Result
= (INT64
)Operand
;
242 return RETURN_SUCCESS
;
244 return SafeUint64ToInt64 ((UINT64
)Operand
, Result
);
248 INT64 -> INTN conversion
250 Converts the value specified by Operand to a value specified by Result type
251 and stores the converted value into the caller allocated output buffer
252 specified by Result. The caller must pass in a Result buffer that is at
253 least as large as the Result type.
255 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
257 If the conversion results in an overflow or an underflow condition, then
258 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
260 @param[in] Operand Operand to be converted to new type
261 @param[out] Result Pointer to the result of conversion
263 @retval RETURN_SUCCESS Successful conversion
264 @retval RETURN_BUFFER_TOO_SMALL Overflow
265 @retval RETURN_INVALID_PARAMETER Result is NULL
274 if (Result
== NULL
) {
275 return RETURN_INVALID_PARAMETER
;
278 if (sizeof (UINTN
) == sizeof (UINT32
)) {
279 return SafeInt64ToInt32 (Operand
, (INT32
*)Result
);
281 *Result
= (INTN
)Operand
;
282 return RETURN_SUCCESS
;
286 INT64 -> UINTN conversion
288 Converts the value specified by Operand to a value specified by Result type
289 and stores the converted value into the caller allocated output buffer
290 specified by Result. The caller must pass in a Result buffer that is at
291 least as large as the Result type.
293 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
295 If the conversion results in an overflow or an underflow condition, then
296 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
298 @param[in] Operand Operand to be converted to new type
299 @param[out] Result Pointer to the result of conversion
301 @retval RETURN_SUCCESS Successful conversion
302 @retval RETURN_BUFFER_TOO_SMALL Overflow
303 @retval RETURN_INVALID_PARAMETER Result is NULL
312 if (sizeof (UINTN
) == sizeof (UINT32
)) {
313 return SafeInt64ToUint32 (Operand
, (UINT32
*)Result
);
315 return SafeInt64ToUint64 (Operand
, (UINT64
*)Result
);
319 UINT64 -> UINTN conversion
321 Converts the value specified by Operand to a value specified by Result type
322 and stores the converted value into the caller allocated output buffer
323 specified by Result. The caller must pass in a Result buffer that is at
324 least as large as the Result type.
326 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
328 If the conversion results in an overflow or an underflow condition, then
329 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
331 @param[in] Operand Operand to be converted to new type
332 @param[out] Result Pointer to the result of conversion
334 @retval RETURN_SUCCESS Successful conversion
335 @retval RETURN_BUFFER_TOO_SMALL Overflow
336 @retval RETURN_INVALID_PARAMETER Result is NULL
345 if (Result
== NULL
) {
346 return RETURN_INVALID_PARAMETER
;
349 if (sizeof (UINTN
) == sizeof (UINT32
)) {
350 return SafeUint64ToUint32 ((UINT64
) Operand
, (UINT32
*)Result
);
353 return RETURN_SUCCESS
;
359 Performs the requested operation using the input parameters into a value
360 specified by Result type and stores the converted value into the caller
361 allocated output buffer specified by Result. The caller must pass in a
362 Result buffer that is at least as large as the Result type.
364 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
366 If the requested operation results in an overflow or an underflow condition,
367 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
369 @param[in] Augend A number to which addend will be added
370 @param[in] Addend A number to be added to another
371 @param[out] Result Pointer to the result of addition
373 @retval RETURN_SUCCESS Successful addition
374 @retval RETURN_BUFFER_TOO_SMALL Overflow
375 @retval RETURN_INVALID_PARAMETER Result is NULL
385 RETURN_STATUS Status
;
387 if (Result
== NULL
) {
388 return RETURN_INVALID_PARAMETER
;
391 if (sizeof (UINTN
) == sizeof (UINT32
)) {
392 if ((UINT32
)(Augend
+ Addend
) >= Augend
) {
393 *Result
= (Augend
+ Addend
);
394 Status
= RETURN_SUCCESS
;
396 *Result
= UINTN_ERROR
;
397 Status
= RETURN_BUFFER_TOO_SMALL
;
402 return SafeUint64Add ((UINT64
)Augend
, (UINT64
)Addend
, (UINT64
*)Result
);
408 Performs the requested operation using the input parameters into a value
409 specified by Result type and stores the converted value into the caller
410 allocated output buffer specified by Result. The caller must pass in a
411 Result buffer that is at least as large as the Result type.
413 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
415 If the requested operation results in an overflow or an underflow condition,
416 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
418 @param[in] Minuend A number from which another is to be subtracted.
419 @param[in] Subtrahend A number to be subtracted from another
420 @param[out] Result Pointer to the result of subtraction
422 @retval RETURN_SUCCESS Successful subtraction
423 @retval RETURN_BUFFER_TOO_SMALL Underflow
424 @retval RETURN_INVALID_PARAMETER Result is NULL
434 RETURN_STATUS Status
;
436 if (Result
== NULL
) {
437 return RETURN_INVALID_PARAMETER
;
440 if (sizeof (UINTN
) == sizeof (UINT32
)) {
441 if (Minuend
>= Subtrahend
) {
442 *Result
= (Minuend
- Subtrahend
);
443 Status
= RETURN_SUCCESS
;
445 *Result
= UINTN_ERROR
;
446 Status
= RETURN_BUFFER_TOO_SMALL
;
451 return SafeUint64Sub ((UINT64
)Minuend
, (UINT64
)Subtrahend
, (UINT64
*)Result
);
457 Performs the requested operation using the input parameters into a value
458 specified by Result type and stores the converted value into the caller
459 allocated output buffer specified by Result. The caller must pass in a
460 Result buffer that is at least as large as the Result type.
462 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
464 If the requested operation results in an overflow or an underflow condition,
465 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
467 @param[in] Multiplicand A number that is to be multiplied by another
468 @param[in] Multiplier A number by which the multiplicand is to be multiplied
469 @param[out] Result Pointer to the result of multiplication
471 @retval RETURN_SUCCESS Successful multiplication
472 @retval RETURN_BUFFER_TOO_SMALL Overflow
473 @retval RETURN_INVALID_PARAMETER Result is NULL
478 IN UINTN Multiplicand
,
483 UINT64 IntermediateResult
;
485 if (sizeof (UINTN
) == sizeof (UINT32
)) {
486 IntermediateResult
= ((UINT64
) Multiplicand
) *((UINT64
) Multiplier
);
488 return SafeUint64ToUintn (IntermediateResult
, Result
);
490 return SafeUint64Mult ((UINT64
)Multiplicand
, (UINT64
)Multiplier
, (UINT64
*)Result
);
496 Performs the requested operation using the input parameters into a value
497 specified by Result type and stores the converted value into the caller
498 allocated output buffer specified by Result. The caller must pass in a
499 Result buffer that is at least as large as the Result type.
501 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
503 If the requested operation results in an overflow or an underflow condition,
504 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
506 @param[in] Augend A number to which addend will be added
507 @param[in] Addend A number to be added to another
508 @param[out] Result Pointer to the result of addition
510 @retval RETURN_SUCCESS Successful addition
511 @retval RETURN_BUFFER_TOO_SMALL Overflow
512 @retval RETURN_INVALID_PARAMETER Result is NULL
522 if (sizeof (UINTN
) == sizeof (UINT32
)) {
523 return SafeInt64ToIntn (((INT64
)Augend
) + ((INT64
)Addend
), Result
);
525 return SafeInt64Add ((INT64
)Augend
, (INT64
)Addend
, (INT64
*)Result
);
531 Performs the requested operation using the input parameters into a value
532 specified by Result type and stores the converted value into the caller
533 allocated output buffer specified by Result. The caller must pass in a
534 Result buffer that is at least as large as the Result type.
536 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
538 If the requested operation results in an overflow or an underflow condition,
539 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
541 @param[in] Minuend A number from which another is to be subtracted.
542 @param[in] Subtrahend A number to be subtracted from another
543 @param[out] Result Pointer to the result of subtraction
545 @retval RETURN_SUCCESS Successful subtraction
546 @retval RETURN_BUFFER_TOO_SMALL Underflow
547 @retval RETURN_INVALID_PARAMETER Result is NULL
557 if (sizeof (UINTN
) == sizeof (UINT32
)) {
558 return SafeInt64ToIntn (((INT64
)Minuend
) - ((INT64
)Subtrahend
), Result
);
560 return SafeInt64Sub ((INT64
)Minuend
, (INT64
)Subtrahend
, (INT64
*)Result
);
566 Performs the requested operation using the input parameters into a value
567 specified by Result type and stores the converted value into the caller
568 allocated output buffer specified by Result. The caller must pass in a
569 Result buffer that is at least as large as the Result type.
571 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
573 If the requested operation results in an overflow or an underflow condition,
574 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
576 @param[in] Multiplicand A number that is to be multiplied by another
577 @param[in] Multiplier A number by which the multiplicand is to be multiplied
578 @param[out] Result Pointer to the result of multiplication
580 @retval RETURN_SUCCESS Successful multiplication
581 @retval RETURN_BUFFER_TOO_SMALL Overflow
582 @retval RETURN_INVALID_PARAMETER Result is NULL
587 IN INTN Multiplicand
,
592 if (sizeof (UINTN
) == sizeof (UINT32
)) {
593 return SafeInt64ToIntn (((INT64
)Multiplicand
) *((INT64
)Multiplier
), Result
);
595 return SafeInt64Mult ((INT64
)Multiplicand
, (INT64
)Multiplier
, (INT64
*)Result
);