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>
33 INT32 -> UINTN conversion
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.
40 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
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.
45 @param[in] Operand Operand to be converted to new type
46 @param[out] Result Pointer to the result of conversion
48 @retval RETURN_SUCCESS Successful conversion
49 @retval RETURN_BUFFER_TOO_SMALL Overflow
50 @retval RETURN_INVALID_PARAMETER Result is NULL
59 return SafeInt32ToUint32 (Operand
, (UINT32
*)Result
);
63 UINT32 -> INTN conversion
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.
70 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
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.
75 @param[in] Operand Operand to be converted to new type
76 @param[out] Result Pointer to the result of conversion
78 @retval RETURN_SUCCESS Successful conversion
79 @retval RETURN_BUFFER_TOO_SMALL Overflow
80 @retval RETURN_INVALID_PARAMETER Result is NULL
89 return SafeUint32ToInt32 (Operand
, (INT32
*)Result
);
93 INTN -> INT32 conversion
95 Converts the value specified by Operand to a value specified by Result type
96 and stores the converted value into the caller allocated output buffer
97 specified by Result. The caller must pass in a Result buffer that is at
98 least as large as the Result type.
100 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
102 If the conversion results in an overflow or an underflow condition, then
103 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
105 @param[in] Operand Operand to be converted to new type
106 @param[out] Result Pointer to the result of conversion
108 @retval RETURN_SUCCESS Successful conversion
109 @retval RETURN_BUFFER_TOO_SMALL Overflow
110 @retval RETURN_INVALID_PARAMETER Result is NULL
119 if (Result
== NULL
) {
120 return RETURN_INVALID_PARAMETER
;
123 *Result
= (INT32
)Operand
;
124 return RETURN_SUCCESS
;
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
;
161 *Result
= (UINT32
)Operand
;
162 Status
= RETURN_SUCCESS
;
164 *Result
= UINT32_ERROR
;
165 Status
= RETURN_BUFFER_TOO_SMALL
;
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 *Result
= (UINT32
)Operand
;
203 return RETURN_SUCCESS
;
207 UINTN -> INT64 conversion
209 Converts the value specified by Operand to a value specified by Result type
210 and stores the converted value into the caller allocated output buffer
211 specified by Result. The caller must pass in a Result buffer that is at
212 least as large as the Result type.
214 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
216 If the conversion results in an overflow or an underflow condition, then
217 Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
219 @param[in] Operand Operand to be converted to new type
220 @param[out] Result Pointer to the result of conversion
222 @retval RETURN_SUCCESS Successful conversion
223 @retval RETURN_BUFFER_TOO_SMALL Overflow
224 @retval RETURN_INVALID_PARAMETER Result is NULL
233 if (Result
== NULL
) {
234 return RETURN_INVALID_PARAMETER
;
237 *Result
= (INT64
)Operand
;
238 return RETURN_SUCCESS
;
242 INT64 -> INTN conversion
244 Converts the value specified by Operand to a value specified by Result type
245 and stores the converted value into the caller allocated output buffer
246 specified by Result. The caller must pass in a Result buffer that is at
247 least as large as the Result type.
249 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
251 If the conversion results in an overflow or an underflow condition, then
252 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
254 @param[in] Operand Operand to be converted to new type
255 @param[out] Result Pointer to the result of conversion
257 @retval RETURN_SUCCESS Successful conversion
258 @retval RETURN_BUFFER_TOO_SMALL Overflow
259 @retval RETURN_INVALID_PARAMETER Result is NULL
268 return SafeInt64ToInt32 (Operand
, (INT32
*)Result
);
272 INT64 -> UINTN conversion
274 Converts the value specified by Operand to a value specified by Result type
275 and stores the converted value into the caller allocated output buffer
276 specified by Result. The caller must pass in a Result buffer that is at
277 least as large as the Result type.
279 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
281 If the conversion results in an overflow or an underflow condition, then
282 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
284 @param[in] Operand Operand to be converted to new type
285 @param[out] Result Pointer to the result of conversion
287 @retval RETURN_SUCCESS Successful conversion
288 @retval RETURN_BUFFER_TOO_SMALL Overflow
289 @retval RETURN_INVALID_PARAMETER Result is NULL
298 return SafeInt64ToUint32 (Operand
, (UINT32
*)Result
);
302 UINT64 -> UINTN conversion
304 Converts the value specified by Operand to a value specified by Result type
305 and stores the converted value into the caller allocated output buffer
306 specified by Result. The caller must pass in a Result buffer that is at
307 least as large as the Result type.
309 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
311 If the conversion results in an overflow or an underflow condition, then
312 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
314 @param[in] Operand Operand to be converted to new type
315 @param[out] Result Pointer to the result of conversion
317 @retval RETURN_SUCCESS Successful conversion
318 @retval RETURN_BUFFER_TOO_SMALL Overflow
319 @retval RETURN_INVALID_PARAMETER Result is NULL
328 return SafeUint64ToUint32 ((UINT64
) Operand
, (UINT32
*)Result
);
334 Performs the requested operation using the input parameters into a value
335 specified by Result type and stores the converted value into the caller
336 allocated output buffer specified by Result. The caller must pass in a
337 Result buffer that is at least as large as the Result type.
339 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
341 If the requested operation results in an overflow or an underflow condition,
342 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
344 @param[in] Augend A number to which addend will be added
345 @param[in] Addend A number to be added to another
346 @param[out] Result Pointer to the result of addition
348 @retval RETURN_SUCCESS Successful addition
349 @retval RETURN_BUFFER_TOO_SMALL Overflow
350 @retval RETURN_INVALID_PARAMETER Result is NULL
360 RETURN_STATUS Status
;
362 if (Result
== NULL
) {
363 return RETURN_INVALID_PARAMETER
;
366 if ((Augend
+ Addend
) >= Augend
) {
367 *Result
= (Augend
+ Addend
);
368 Status
= RETURN_SUCCESS
;
370 *Result
= UINTN_ERROR
;
371 Status
= RETURN_BUFFER_TOO_SMALL
;
380 Performs the requested operation using the input parameters into a value
381 specified by Result type and stores the converted value into the caller
382 allocated output buffer specified by Result. The caller must pass in a
383 Result buffer that is at least as large as the Result type.
385 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
387 If the requested operation results in an overflow or an underflow condition,
388 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
390 @param[in] Minuend A number from which another is to be subtracted.
391 @param[in] Subtrahend A number to be subtracted from another
392 @param[out] Result Pointer to the result of subtraction
394 @retval RETURN_SUCCESS Successful subtraction
395 @retval RETURN_BUFFER_TOO_SMALL Underflow
396 @retval RETURN_INVALID_PARAMETER Result is NULL
406 RETURN_STATUS Status
;
408 if (Result
== NULL
) {
409 return RETURN_INVALID_PARAMETER
;
412 if (Minuend
>= Subtrahend
) {
413 *Result
= (Minuend
- Subtrahend
);
414 Status
= RETURN_SUCCESS
;
416 *Result
= UINTN_ERROR
;
417 Status
= RETURN_BUFFER_TOO_SMALL
;
426 Performs the requested operation using the input parameters into a value
427 specified by Result type and stores the converted value into the caller
428 allocated output buffer specified by Result. The caller must pass in a
429 Result buffer that is at least as large as the Result type.
431 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
433 If the requested operation results in an overflow or an underflow condition,
434 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
436 @param[in] Multiplicand A number that is to be multiplied by another
437 @param[in] Multiplier A number by which the multiplicand is to be multiplied
438 @param[out] Result Pointer to the result of multiplication
440 @retval RETURN_SUCCESS Successful multiplication
441 @retval RETURN_BUFFER_TOO_SMALL Overflow
442 @retval RETURN_INVALID_PARAMETER Result is NULL
447 IN UINTN Multiplicand
,
452 UINT64 IntermediateResult
;
454 IntermediateResult
= ((UINT64
) Multiplicand
) *((UINT64
) Multiplier
);
456 return SafeUint64ToUintn (IntermediateResult
, Result
);
462 Performs the requested operation using the input parameters into a value
463 specified by Result type and stores the converted value into the caller
464 allocated output buffer specified by Result. The caller must pass in a
465 Result buffer that is at least as large as the Result type.
467 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
469 If the requested operation results in an overflow or an underflow condition,
470 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
472 @param[in] Augend A number to which addend will be added
473 @param[in] Addend A number to be added to another
474 @param[out] Result Pointer to the result of addition
476 @retval RETURN_SUCCESS Successful addition
477 @retval RETURN_BUFFER_TOO_SMALL Overflow
478 @retval RETURN_INVALID_PARAMETER Result is NULL
488 return SafeInt64ToIntn (((INT64
)Augend
) + ((INT64
)Addend
), Result
);
494 Performs the requested operation using the input parameters into a value
495 specified by Result type and stores the converted value into the caller
496 allocated output buffer specified by Result. The caller must pass in a
497 Result buffer that is at least as large as the Result type.
499 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
501 If the requested operation results in an overflow or an underflow condition,
502 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
504 @param[in] Minuend A number from which another is to be subtracted.
505 @param[in] Subtrahend A number to be subtracted from another
506 @param[out] Result Pointer to the result of subtraction
508 @retval RETURN_SUCCESS Successful subtraction
509 @retval RETURN_BUFFER_TOO_SMALL Underflow
510 @retval RETURN_INVALID_PARAMETER Result is NULL
520 return SafeInt64ToIntn (((INT64
)Minuend
) - ((INT64
)Subtrahend
), Result
);
526 Performs the requested operation using the input parameters into a value
527 specified by Result type and stores the converted value into the caller
528 allocated output buffer specified by Result. The caller must pass in a
529 Result buffer that is at least as large as the Result type.
531 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
533 If the requested operation results in an overflow or an underflow condition,
534 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
536 @param[in] Multiplicand A number that is to be multiplied by another
537 @param[in] Multiplier A number by which the multiplicand is to be multiplied
538 @param[out] Result Pointer to the result of multiplication
540 @retval RETURN_SUCCESS Successful multiplication
541 @retval RETURN_BUFFER_TOO_SMALL Overflow
542 @retval RETURN_INVALID_PARAMETER Result is NULL
547 IN INTN Multiplicand
,
552 return SafeInt64ToIntn (((INT64
)Multiplicand
) *((INT64
)Multiplier
), Result
);