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>
14 #include <Library/BaseLib.h>
17 INT32 -> UINTN conversion
19 Converts the value specified by Operand to a value specified by Result type
20 and stores the converted value into the caller allocated output buffer
21 specified by Result. The caller must pass in a Result buffer that is at
22 least as large as the Result type.
24 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
26 If the conversion results in an overflow or an underflow condition, then
27 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
29 @param[in] Operand Operand to be converted to new type
30 @param[out] Result Pointer to the result of conversion
32 @retval RETURN_SUCCESS Successful conversion
33 @retval RETURN_BUFFER_TOO_SMALL Overflow
34 @retval RETURN_INVALID_PARAMETER Result is NULL
43 return SafeInt32ToUint32 (Operand
, (UINT32
*)Result
);
47 UINT32 -> INTN conversion
49 Converts the value specified by Operand to a value specified by Result type
50 and stores the converted value into the caller allocated output buffer
51 specified by Result. The caller must pass in a Result buffer that is at
52 least as large as the Result type.
54 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
56 If the conversion results in an overflow or an underflow condition, then
57 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
59 @param[in] Operand Operand to be converted to new type
60 @param[out] Result Pointer to the result of conversion
62 @retval RETURN_SUCCESS Successful conversion
63 @retval RETURN_BUFFER_TOO_SMALL Overflow
64 @retval RETURN_INVALID_PARAMETER Result is NULL
73 return SafeUint32ToInt32 (Operand
, (INT32
*)Result
);
77 INTN -> INT32 conversion
79 Converts the value specified by Operand to a value specified by Result type
80 and stores the converted value into the caller allocated output buffer
81 specified by Result. The caller must pass in a Result buffer that is at
82 least as large as the Result type.
84 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
86 If the conversion results in an overflow or an underflow condition, then
87 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
89 @param[in] Operand Operand to be converted to new type
90 @param[out] Result Pointer to the result of conversion
92 @retval RETURN_SUCCESS Successful conversion
93 @retval RETURN_BUFFER_TOO_SMALL Overflow
94 @retval RETURN_INVALID_PARAMETER Result is NULL
103 if (Result
== NULL
) {
104 return RETURN_INVALID_PARAMETER
;
107 *Result
= (INT32
)Operand
;
108 return RETURN_SUCCESS
;
112 INTN -> UINT32 conversion
114 Converts the value specified by Operand to a value specified by Result type
115 and stores the converted value into the caller allocated output buffer
116 specified by Result. The caller must pass in a Result buffer that is at
117 least as large as the Result type.
119 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
121 If the conversion results in an overflow or an underflow condition, then
122 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
124 @param[in] Operand Operand to be converted to new type
125 @param[out] Result Pointer to the result of conversion
127 @retval RETURN_SUCCESS Successful conversion
128 @retval RETURN_BUFFER_TOO_SMALL Overflow
129 @retval RETURN_INVALID_PARAMETER Result is NULL
138 RETURN_STATUS Status
;
140 if (Result
== NULL
) {
141 return RETURN_INVALID_PARAMETER
;
145 *Result
= (UINT32
)Operand
;
146 Status
= RETURN_SUCCESS
;
148 *Result
= UINT32_ERROR
;
149 Status
= RETURN_BUFFER_TOO_SMALL
;
156 UINTN -> UINT32 conversion
158 Converts the value specified by Operand to a value specified by Result type
159 and stores the converted value into the caller allocated output buffer
160 specified by Result. The caller must pass in a Result buffer that is at
161 least as large as the Result type.
163 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
165 If the conversion results in an overflow or an underflow condition, then
166 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
168 @param[in] Operand Operand to be converted to new type
169 @param[out] Result Pointer to the result of conversion
171 @retval RETURN_SUCCESS Successful conversion
172 @retval RETURN_BUFFER_TOO_SMALL Overflow
173 @retval RETURN_INVALID_PARAMETER Result is NULL
182 if (Result
== NULL
) {
183 return RETURN_INVALID_PARAMETER
;
186 *Result
= (UINT32
)Operand
;
187 return RETURN_SUCCESS
;
191 UINTN -> INT64 conversion
193 Converts the value specified by Operand to a value specified by Result type
194 and stores the converted value into the caller allocated output buffer
195 specified by Result. The caller must pass in a Result buffer that is at
196 least as large as the Result type.
198 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
200 If the conversion results in an overflow or an underflow condition, then
201 Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
203 @param[in] Operand Operand to be converted to new type
204 @param[out] Result Pointer to the result of conversion
206 @retval RETURN_SUCCESS Successful conversion
207 @retval RETURN_BUFFER_TOO_SMALL Overflow
208 @retval RETURN_INVALID_PARAMETER Result is NULL
217 if (Result
== NULL
) {
218 return RETURN_INVALID_PARAMETER
;
221 *Result
= (INT64
)Operand
;
222 return RETURN_SUCCESS
;
226 INT64 -> INTN conversion
228 Converts the value specified by Operand to a value specified by Result type
229 and stores the converted value into the caller allocated output buffer
230 specified by Result. The caller must pass in a Result buffer that is at
231 least as large as the Result type.
233 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
235 If the conversion results in an overflow or an underflow condition, then
236 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
238 @param[in] Operand Operand to be converted to new type
239 @param[out] Result Pointer to the result of conversion
241 @retval RETURN_SUCCESS Successful conversion
242 @retval RETURN_BUFFER_TOO_SMALL Overflow
243 @retval RETURN_INVALID_PARAMETER Result is NULL
252 return SafeInt64ToInt32 (Operand
, (INT32
*)Result
);
256 INT64 -> UINTN conversion
258 Converts the value specified by Operand to a value specified by Result type
259 and stores the converted value into the caller allocated output buffer
260 specified by Result. The caller must pass in a Result buffer that is at
261 least as large as the Result type.
263 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
265 If the conversion results in an overflow or an underflow condition, then
266 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
268 @param[in] Operand Operand to be converted to new type
269 @param[out] Result Pointer to the result of conversion
271 @retval RETURN_SUCCESS Successful conversion
272 @retval RETURN_BUFFER_TOO_SMALL Overflow
273 @retval RETURN_INVALID_PARAMETER Result is NULL
282 return SafeInt64ToUint32 (Operand
, (UINT32
*)Result
);
286 UINT64 -> 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 return SafeUint64ToUint32 ((UINT64
)Operand
, (UINT32
*)Result
);
318 Performs the requested operation using the input parameters into a value
319 specified by Result type and stores the converted value into the caller
320 allocated output buffer specified by Result. The caller must pass in a
321 Result buffer that is at least as large as the Result type.
323 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
325 If the requested operation results in an overflow or an underflow condition,
326 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
328 @param[in] Augend A number to which addend will be added
329 @param[in] Addend A number to be added to another
330 @param[out] Result Pointer to the result of addition
332 @retval RETURN_SUCCESS Successful addition
333 @retval RETURN_BUFFER_TOO_SMALL Overflow
334 @retval RETURN_INVALID_PARAMETER Result is NULL
344 RETURN_STATUS Status
;
346 if (Result
== NULL
) {
347 return RETURN_INVALID_PARAMETER
;
350 if ((Augend
+ Addend
) >= Augend
) {
351 *Result
= (Augend
+ Addend
);
352 Status
= RETURN_SUCCESS
;
354 *Result
= UINTN_ERROR
;
355 Status
= RETURN_BUFFER_TOO_SMALL
;
364 Performs the requested operation using the input parameters into a value
365 specified by Result type and stores the converted value into the caller
366 allocated output buffer specified by Result. The caller must pass in a
367 Result buffer that is at least as large as the Result type.
369 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
371 If the requested operation results in an overflow or an underflow condition,
372 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
374 @param[in] Minuend A number from which another is to be subtracted.
375 @param[in] Subtrahend A number to be subtracted from another
376 @param[out] Result Pointer to the result of subtraction
378 @retval RETURN_SUCCESS Successful subtraction
379 @retval RETURN_BUFFER_TOO_SMALL Underflow
380 @retval RETURN_INVALID_PARAMETER Result is NULL
390 RETURN_STATUS Status
;
392 if (Result
== NULL
) {
393 return RETURN_INVALID_PARAMETER
;
396 if (Minuend
>= Subtrahend
) {
397 *Result
= (Minuend
- Subtrahend
);
398 Status
= RETURN_SUCCESS
;
400 *Result
= UINTN_ERROR
;
401 Status
= RETURN_BUFFER_TOO_SMALL
;
410 Performs the requested operation using the input parameters into a value
411 specified by Result type and stores the converted value into the caller
412 allocated output buffer specified by Result. The caller must pass in a
413 Result buffer that is at least as large as the Result type.
415 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
417 If the requested operation results in an overflow or an underflow condition,
418 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
420 @param[in] Multiplicand A number that is to be multiplied by another
421 @param[in] Multiplier A number by which the multiplicand is to be multiplied
422 @param[out] Result Pointer to the result of multiplication
424 @retval RETURN_SUCCESS Successful multiplication
425 @retval RETURN_BUFFER_TOO_SMALL Overflow
426 @retval RETURN_INVALID_PARAMETER Result is NULL
431 IN UINTN Multiplicand
,
436 UINT64 IntermediateResult
;
438 IntermediateResult
= ((UINT64
)Multiplicand
) *((UINT64
)Multiplier
);
440 return SafeUint64ToUintn (IntermediateResult
, Result
);
446 Performs the requested operation using the input parameters into a value
447 specified by Result type and stores the converted value into the caller
448 allocated output buffer specified by Result. The caller must pass in a
449 Result buffer that is at least as large as the Result type.
451 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
453 If the requested operation results in an overflow or an underflow condition,
454 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
456 @param[in] Augend A number to which addend will be added
457 @param[in] Addend A number to be added to another
458 @param[out] Result Pointer to the result of addition
460 @retval RETURN_SUCCESS Successful addition
461 @retval RETURN_BUFFER_TOO_SMALL Overflow
462 @retval RETURN_INVALID_PARAMETER Result is NULL
472 return SafeInt64ToIntn (((INT64
)Augend
) + ((INT64
)Addend
), Result
);
478 Performs the requested operation using the input parameters into a value
479 specified by Result type and stores the converted value into the caller
480 allocated output buffer specified by Result. The caller must pass in a
481 Result buffer that is at least as large as the Result type.
483 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
485 If the requested operation results in an overflow or an underflow condition,
486 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
488 @param[in] Minuend A number from which another is to be subtracted.
489 @param[in] Subtrahend A number to be subtracted from another
490 @param[out] Result Pointer to the result of subtraction
492 @retval RETURN_SUCCESS Successful subtraction
493 @retval RETURN_BUFFER_TOO_SMALL Underflow
494 @retval RETURN_INVALID_PARAMETER Result is NULL
504 return SafeInt64ToIntn (((INT64
)Minuend
) - ((INT64
)Subtrahend
), Result
);
510 Performs the requested operation using the input parameters into a value
511 specified by Result type and stores the converted value into the caller
512 allocated output buffer specified by Result. The caller must pass in a
513 Result buffer that is at least as large as the Result type.
515 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
517 If the requested operation results in an overflow or an underflow condition,
518 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
520 @param[in] Multiplicand A number that is to be multiplied by another
521 @param[in] Multiplier A number by which the multiplicand is to be multiplied
522 @param[out] Result Pointer to the result of multiplication
524 @retval RETURN_SUCCESS Successful multiplication
525 @retval RETURN_BUFFER_TOO_SMALL Overflow
526 @retval RETURN_INVALID_PARAMETER Result is NULL
531 IN INTN Multiplicand
,
536 return SafeInt64ToIntn (MultS64x64 (Multiplicand
, Multiplier
), Result
);