]>
git.proxmox.com Git - libgit2.git/blob - src/integer.h
2 * Copyright (C) the libgit2 contributors. All rights reserved.
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
7 #ifndef INCLUDE_integer_h__
8 #define INCLUDE_integer_h__
10 /** @return true if p fits into the range of a size_t */
11 GIT_INLINE(int) git__is_sizet(int64_t p
)
14 return p
== (int64_t)r
;
17 /** @return true if p fits into the range of an ssize_t */
18 GIT_INLINE(int) git__is_ssizet(size_t p
)
20 ssize_t r
= (ssize_t
)p
;
21 return p
== (size_t)r
;
24 /** @return true if p fits into the range of a uint16_t */
25 GIT_INLINE(int) git__is_uint16(size_t p
)
27 uint16_t r
= (uint16_t)p
;
28 return p
== (size_t)r
;
31 /** @return true if p fits into the range of a uint32_t */
32 GIT_INLINE(int) git__is_uint32(size_t p
)
34 uint32_t r
= (uint32_t)p
;
35 return p
== (size_t)r
;
38 /** @return true if p fits into the range of an unsigned long */
39 GIT_INLINE(int) git__is_ulong(int64_t p
)
41 unsigned long r
= (unsigned long)p
;
42 return p
== (int64_t)r
;
45 /** @return true if p fits into the range of an int */
46 GIT_INLINE(int) git__is_int(long long p
)
49 return p
== (long long)r
;
52 /* Use clang/gcc compiler intrinsics whenever possible */
53 #if (__has_builtin(__builtin_add_overflow) || \
54 (defined(__GNUC__) && (__GNUC__ >= 5)))
56 # if (SIZE_MAX == UINT_MAX)
57 # define git__add_sizet_overflow(out, one, two) \
58 __builtin_uadd_overflow(one, two, out)
59 # define git__multiply_sizet_overflow(out, one, two) \
60 __builtin_umul_overflow(one, two, out)
61 # elif (SIZE_MAX == ULONG_MAX)
62 # define git__add_sizet_overflow(out, one, two) \
63 __builtin_uaddl_overflow(one, two, out)
64 # define git__multiply_sizet_overflow(out, one, two) \
65 __builtin_umull_overflow(one, two, out)
66 # elif (SIZE_MAX == ULLONG_MAX)
67 # define git__add_sizet_overflow(out, one, two) \
68 __builtin_uaddll_overflow(one, two, out)
69 # define git__multiply_sizet_overflow(out, one, two) \
70 __builtin_umulll_overflow(one, two, out)
72 # error compiler has add with overflow intrinsics but SIZE_MAX is unknown
75 # define git__add_int_overflow(out, one, two) \
76 __builtin_sadd_overflow(one, two, out)
77 # define git__sub_int_overflow(out, one, two) \
78 __builtin_ssub_overflow(one, two, out)
80 /* Use Microsoft's safe integer handling functions where available */
81 #elif defined(_MSC_VER)
83 # define ENABLE_INTSAFE_SIGNED_FUNCTIONS
86 # define git__add_sizet_overflow(out, one, two) \
87 (SizeTAdd(one, two, out) != S_OK)
88 # define git__multiply_sizet_overflow(out, one, two) \
89 (SizeTMult(one, two, out) != S_OK)
90 #define git__add_int_overflow(out, one, two) \
91 (IntAdd(one, two, out) != S_OK)
92 #define git__sub_int_overflow(out, one, two) \
93 (IntSub(one, two, out) != S_OK)
98 * Sets `one + two` into `out`, unless the arithmetic would overflow.
99 * @return false if the result fits in a `size_t`, true on overflow.
101 GIT_INLINE(bool) git__add_sizet_overflow(size_t *out
, size_t one
, size_t two
)
103 if (SIZE_MAX
- one
< two
)
110 * Sets `one * two` into `out`, unless the arithmetic would overflow.
111 * @return false if the result fits in a `size_t`, true on overflow.
113 GIT_INLINE(bool) git__multiply_sizet_overflow(size_t *out
, size_t one
, size_t two
)
115 if (one
&& SIZE_MAX
/ one
< two
)
121 GIT_INLINE(bool) git__add_int_overflow(int *out
, int one
, int two
)
123 if ((two
> 0 && one
> (INT_MAX
- two
)) ||
124 (two
< 0 && one
< (INT_MIN
- two
)))
130 GIT_INLINE(bool) git__sub_int_overflow(int *out
, int one
, int two
)
132 if ((two
> 0 && one
< (INT_MIN
+ two
)) ||
133 (two
< 0 && one
> (INT_MAX
+ two
)))