File Coverage

deps/libgit2/src/integer.h
Criterion Covered Total %
statement 0 3 0.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 0 3 0.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (C) the libgit2 contributors. All rights reserved.
3             *
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.
6             */
7             #ifndef INCLUDE_integer_h__
8             #define INCLUDE_integer_h__
9              
10             /** @return true if p fits into the range of a size_t */
11 0           GIT_INLINE(int) git__is_sizet(int64_t p)
12             {
13 0           size_t r = (size_t)p;
14 0           return p == (int64_t)r;
15             }
16              
17             /** @return true if p fits into the range of an ssize_t */
18             GIT_INLINE(int) git__is_ssizet(size_t p)
19             {
20             ssize_t r = (ssize_t)p;
21             return p == (size_t)r;
22             }
23              
24             /** @return true if p fits into the range of a uint16_t */
25             GIT_INLINE(int) git__is_uint16(size_t p)
26             {
27             uint16_t r = (uint16_t)p;
28             return p == (size_t)r;
29             }
30              
31             /** @return true if p fits into the range of a uint32_t */
32             GIT_INLINE(int) git__is_uint32(size_t p)
33             {
34             uint32_t r = (uint32_t)p;
35             return p == (size_t)r;
36             }
37              
38             /** @return true if p fits into the range of an unsigned long */
39             GIT_INLINE(int) git__is_ulong(int64_t p)
40             {
41             unsigned long r = (unsigned long)p;
42             return p == (int64_t)r;
43             }
44              
45             /** @return true if p fits into the range of an int */
46             GIT_INLINE(int) git__is_int(long long p)
47             {
48             int r = (int)p;
49             return p == (long long)r;
50             }
51              
52             /* Use clang/gcc compiler intrinsics whenever possible */
53             #if (__has_builtin(__builtin_add_overflow) || \
54             (defined(__GNUC__) && (__GNUC__ >= 5)))
55              
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)
71             # else
72             # error compiler has add with overflow intrinsics but SIZE_MAX is unknown
73             # endif
74              
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)
79              
80             /* Use Microsoft's safe integer handling functions where available */
81             #elif defined(_MSC_VER)
82              
83             # define ENABLE_INTSAFE_SIGNED_FUNCTIONS
84             # include
85              
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)
94              
95             #else
96              
97             /**
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.
100             */
101             GIT_INLINE(bool) git__add_sizet_overflow(size_t *out, size_t one, size_t two)
102             {
103             if (SIZE_MAX - one < two)
104             return true;
105             *out = one + two;
106             return false;
107             }
108              
109             /**
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.
112             */
113             GIT_INLINE(bool) git__multiply_sizet_overflow(size_t *out, size_t one, size_t two)
114             {
115             if (one && SIZE_MAX / one < two)
116             return true;
117             *out = one * two;
118             return false;
119             }
120              
121             GIT_INLINE(bool) git__add_int_overflow(int *out, int one, int two)
122             {
123             if ((two > 0 && one > (INT_MAX - two)) ||
124             (two < 0 && one < (INT_MIN - two)))
125             return true;
126             *out = one + two;
127             return false;
128             }
129              
130             GIT_INLINE(bool) git__sub_int_overflow(int *out, int one, int two)
131             {
132             if ((two > 0 && one < (INT_MIN + two)) ||
133             (two < 0 && one > (INT_MAX + two)))
134             return true;
135             *out = one - two;
136             return false;
137             }
138              
139             #endif
140              
141             #endif