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 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.
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.
30 #include <Library/SafeIntLib.h>
31 #include <Library/BaseLib.h>
34 INT32 -> UINTN conversion
36 Converts the value specified by Operand to a value specified by Result type
37 and stores the converted value into the caller allocated output buffer
38 specified by Result. The caller must pass in a Result buffer that is at
39 least as large as the Result type.
41 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
43 If the conversion results in an overflow or an underflow condition, then
44 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
46 @param[in] Operand Operand to be converted to new type
47 @param[out] Result Pointer to the result of conversion
49 @retval RETURN_SUCCESS Successful conversion
50 @retval RETURN_BUFFER_TOO_SMALL Overflow
51 @retval RETURN_INVALID_PARAMETER Result is NULL
60 return SafeInt32ToUint32 (Operand
, (UINT32
*)Result
);
64 UINT32 -> INTN conversion
66 Converts the value specified by Operand to a value specified by Result type
67 and stores the converted value into the caller allocated output buffer
68 specified by Result. The caller must pass in a Result buffer that is at
69 least as large as the Result type.
71 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
73 If the conversion results in an overflow or an underflow condition, then
74 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
76 @param[in] Operand Operand to be converted to new type
77 @param[out] Result Pointer to the result of conversion
79 @retval RETURN_SUCCESS Successful conversion
80 @retval RETURN_BUFFER_TOO_SMALL Overflow
81 @retval RETURN_INVALID_PARAMETER Result is NULL
90 return SafeUint32ToInt32 (Operand
, (INT32
*)Result
);
94 INTN -> INT32 conversion
96 Converts the value specified by Operand to a value specified by Result type
97 and stores the converted value into the caller allocated output buffer
98 specified by Result. The caller must pass in a Result buffer that is at
99 least as large as the Result type.
101 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
103 If the conversion results in an overflow or an underflow condition, then
104 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
106 @param[in] Operand Operand to be converted to new type
107 @param[out] Result Pointer to the result of conversion
109 @retval RETURN_SUCCESS Successful conversion
110 @retval RETURN_BUFFER_TOO_SMALL Overflow
111 @retval RETURN_INVALID_PARAMETER Result is NULL
120 if (Result
== NULL
) {
121 return RETURN_INVALID_PARAMETER
;
124 *Result
= (INT32
)Operand
;
125 return RETURN_SUCCESS
;
129 INTN -> UINT32 conversion
131 Converts the value specified by Operand to a value specified by Result type
132 and stores the converted value into the caller allocated output buffer
133 specified by Result. The caller must pass in a Result buffer that is at
134 least as large as the Result type.
136 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
138 If the conversion results in an overflow or an underflow condition, then
139 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
141 @param[in] Operand Operand to be converted to new type
142 @param[out] Result Pointer to the result of conversion
144 @retval RETURN_SUCCESS Successful conversion
145 @retval RETURN_BUFFER_TOO_SMALL Overflow
146 @retval RETURN_INVALID_PARAMETER Result is NULL
155 RETURN_STATUS Status
;
157 if (Result
== NULL
) {
158 return RETURN_INVALID_PARAMETER
;
162 *Result
= (UINT32
)Operand
;
163 Status
= RETURN_SUCCESS
;
165 *Result
= UINT32_ERROR
;
166 Status
= RETURN_BUFFER_TOO_SMALL
;
173 UINTN -> UINT32 conversion
175 Converts the value specified by Operand to a value specified by Result type
176 and stores the converted value into the caller allocated output buffer
177 specified by Result. The caller must pass in a Result buffer that is at
178 least as large as the Result type.
180 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
182 If the conversion results in an overflow or an underflow condition, then
183 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
185 @param[in] Operand Operand to be converted to new type
186 @param[out] Result Pointer to the result of conversion
188 @retval RETURN_SUCCESS Successful conversion
189 @retval RETURN_BUFFER_TOO_SMALL Overflow
190 @retval RETURN_INVALID_PARAMETER Result is NULL
199 if (Result
== NULL
) {
200 return RETURN_INVALID_PARAMETER
;
203 *Result
= (UINT32
)Operand
;
204 return RETURN_SUCCESS
;
208 UINTN -> INT64 conversion
210 Converts the value specified by Operand to a value specified by Result type
211 and stores the converted value into the caller allocated output buffer
212 specified by Result. The caller must pass in a Result buffer that is at
213 least as large as the Result type.
215 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
217 If the conversion results in an overflow or an underflow condition, then
218 Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
220 @param[in] Operand Operand to be converted to new type
221 @param[out] Result Pointer to the result of conversion
223 @retval RETURN_SUCCESS Successful conversion
224 @retval RETURN_BUFFER_TOO_SMALL Overflow
225 @retval RETURN_INVALID_PARAMETER Result is NULL
234 if (Result
== NULL
) {
235 return RETURN_INVALID_PARAMETER
;
238 *Result
= (INT64
)Operand
;
239 return RETURN_SUCCESS
;
243 INT64 -> INTN conversion
245 Converts the value specified by Operand to a value specified by Result type
246 and stores the converted value into the caller allocated output buffer
247 specified by Result. The caller must pass in a Result buffer that is at
248 least as large as the Result type.
250 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
252 If the conversion results in an overflow or an underflow condition, then
253 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
255 @param[in] Operand Operand to be converted to new type
256 @param[out] Result Pointer to the result of conversion
258 @retval RETURN_SUCCESS Successful conversion
259 @retval RETURN_BUFFER_TOO_SMALL Overflow
260 @retval RETURN_INVALID_PARAMETER Result is NULL
269 return SafeInt64ToInt32 (Operand
, (INT32
*)Result
);
273 INT64 -> UINTN conversion
275 Converts the value specified by Operand to a value specified by Result type
276 and stores the converted value into the caller allocated output buffer
277 specified by Result. The caller must pass in a Result buffer that is at
278 least as large as the Result type.
280 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
282 If the conversion results in an overflow or an underflow condition, then
283 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
285 @param[in] Operand Operand to be converted to new type
286 @param[out] Result Pointer to the result of conversion
288 @retval RETURN_SUCCESS Successful conversion
289 @retval RETURN_BUFFER_TOO_SMALL Overflow
290 @retval RETURN_INVALID_PARAMETER Result is NULL
299 return SafeInt64ToUint32 (Operand
, (UINT32
*)Result
);
303 UINT64 -> UINTN conversion
305 Converts the value specified by Operand to a value specified by Result type
306 and stores the converted value into the caller allocated output buffer
307 specified by Result. The caller must pass in a Result buffer that is at
308 least as large as the Result type.
310 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
312 If the conversion results in an overflow or an underflow condition, then
313 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
315 @param[in] Operand Operand to be converted to new type
316 @param[out] Result Pointer to the result of conversion
318 @retval RETURN_SUCCESS Successful conversion
319 @retval RETURN_BUFFER_TOO_SMALL Overflow
320 @retval RETURN_INVALID_PARAMETER Result is NULL
329 return SafeUint64ToUint32 ((UINT64
) Operand
, (UINT32
*)Result
);
335 Performs the requested operation using the input parameters into a value
336 specified by Result type and stores the converted value into the caller
337 allocated output buffer specified by Result. The caller must pass in a
338 Result buffer that is at least as large as the Result type.
340 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
342 If the requested operation results in an overflow or an underflow condition,
343 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
345 @param[in] Augend A number to which addend will be added
346 @param[in] Addend A number to be added to another
347 @param[out] Result Pointer to the result of addition
349 @retval RETURN_SUCCESS Successful addition
350 @retval RETURN_BUFFER_TOO_SMALL Overflow
351 @retval RETURN_INVALID_PARAMETER Result is NULL
361 RETURN_STATUS Status
;
363 if (Result
== NULL
) {
364 return RETURN_INVALID_PARAMETER
;
367 if ((Augend
+ Addend
) >= Augend
) {
368 *Result
= (Augend
+ Addend
);
369 Status
= RETURN_SUCCESS
;
371 *Result
= UINTN_ERROR
;
372 Status
= RETURN_BUFFER_TOO_SMALL
;
381 Performs the requested operation using the input parameters into a value
382 specified by Result type and stores the converted value into the caller
383 allocated output buffer specified by Result. The caller must pass in a
384 Result buffer that is at least as large as the Result type.
386 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
388 If the requested operation results in an overflow or an underflow condition,
389 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
391 @param[in] Minuend A number from which another is to be subtracted.
392 @param[in] Subtrahend A number to be subtracted from another
393 @param[out] Result Pointer to the result of subtraction
395 @retval RETURN_SUCCESS Successful subtraction
396 @retval RETURN_BUFFER_TOO_SMALL Underflow
397 @retval RETURN_INVALID_PARAMETER Result is NULL
407 RETURN_STATUS Status
;
409 if (Result
== NULL
) {
410 return RETURN_INVALID_PARAMETER
;
413 if (Minuend
>= Subtrahend
) {
414 *Result
= (Minuend
- Subtrahend
);
415 Status
= RETURN_SUCCESS
;
417 *Result
= UINTN_ERROR
;
418 Status
= RETURN_BUFFER_TOO_SMALL
;
427 Performs the requested operation using the input parameters into a value
428 specified by Result type and stores the converted value into the caller
429 allocated output buffer specified by Result. The caller must pass in a
430 Result buffer that is at least as large as the Result type.
432 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
434 If the requested operation results in an overflow or an underflow condition,
435 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
437 @param[in] Multiplicand A number that is to be multiplied by another
438 @param[in] Multiplier A number by which the multiplicand is to be multiplied
439 @param[out] Result Pointer to the result of multiplication
441 @retval RETURN_SUCCESS Successful multiplication
442 @retval RETURN_BUFFER_TOO_SMALL Overflow
443 @retval RETURN_INVALID_PARAMETER Result is NULL
448 IN UINTN Multiplicand
,
453 UINT64 IntermediateResult
;
455 IntermediateResult
= ((UINT64
) Multiplicand
) *((UINT64
) Multiplier
);
457 return SafeUint64ToUintn (IntermediateResult
, Result
);
463 Performs the requested operation using the input parameters into a value
464 specified by Result type and stores the converted value into the caller
465 allocated output buffer specified by Result. The caller must pass in a
466 Result buffer that is at least as large as the Result type.
468 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
470 If the requested operation results in an overflow or an underflow condition,
471 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
473 @param[in] Augend A number to which addend will be added
474 @param[in] Addend A number to be added to another
475 @param[out] Result Pointer to the result of addition
477 @retval RETURN_SUCCESS Successful addition
478 @retval RETURN_BUFFER_TOO_SMALL Overflow
479 @retval RETURN_INVALID_PARAMETER Result is NULL
489 return SafeInt64ToIntn (((INT64
)Augend
) + ((INT64
)Addend
), Result
);
495 Performs the requested operation using the input parameters into a value
496 specified by Result type and stores the converted value into the caller
497 allocated output buffer specified by Result. The caller must pass in a
498 Result buffer that is at least as large as the Result type.
500 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
502 If the requested operation results in an overflow or an underflow condition,
503 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
505 @param[in] Minuend A number from which another is to be subtracted.
506 @param[in] Subtrahend A number to be subtracted from another
507 @param[out] Result Pointer to the result of subtraction
509 @retval RETURN_SUCCESS Successful subtraction
510 @retval RETURN_BUFFER_TOO_SMALL Underflow
511 @retval RETURN_INVALID_PARAMETER Result is NULL
521 return SafeInt64ToIntn (((INT64
)Minuend
) - ((INT64
)Subtrahend
), Result
);
527 Performs the requested operation using the input parameters into a value
528 specified by Result type and stores the converted value into the caller
529 allocated output buffer specified by Result. The caller must pass in a
530 Result buffer that is at least as large as the Result type.
532 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
534 If the requested operation results in an overflow or an underflow condition,
535 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
537 @param[in] Multiplicand A number that is to be multiplied by another
538 @param[in] Multiplier A number by which the multiplicand is to be multiplied
539 @param[out] Result Pointer to the result of multiplication
541 @retval RETURN_SUCCESS Successful multiplication
542 @retval RETURN_BUFFER_TOO_SMALL Overflow
543 @retval RETURN_INVALID_PARAMETER Result is NULL
548 IN INTN Multiplicand
,
553 return SafeInt64ToIntn (MultS64x64 (Multiplicand
, Multiplier
), Result
);