Skip to content

Commit b09c1c7

Browse files
committed
util: avoid signed integer overflows in git__strntol64
While `git__strntol64` tries to detect integer overflows when doing the necessary arithmetics to come up with the final result, it does the detection only after the fact. This check thus relies on undefined behavior of signed integer overflows. Fix this by instead checking up-front whether the multiplications or additions will overflow. Note that a detected overflow will not cause us to abort parsing the current sequence of digits. In the case of an overflow, previous behavior was to still set up the end pointer correctly to point to the first character immediately after the currently parsed number. We do not want to change this now as code may rely on the end pointer being set up correctly even if the parsed number is too big to be represented as 64 bit integer.
1 parent 39087ab commit b09c1c7

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

src/util.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,20 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha
126126
v = c - 'A' + 10;
127127
if (v >= base)
128128
break;
129-
nn = n * base + (neg ? -v : v);
130-
if ((!neg && nn < n) || (neg && nn > n))
129+
v = neg ? -v : v;
130+
if (n > INT64_MAX / base || n < INT64_MIN / base) {
131131
ovfl = 1;
132-
n = nn;
132+
/* Keep on iterating until the end of this number */
133+
continue;
134+
}
135+
nn = n * base;
136+
if ((v > 0 && nn > INT64_MAX - v) ||
137+
(v < 0 && nn < INT64_MIN - v)) {
138+
ovfl = 1;
139+
/* Keep on iterating until the end of this number */
140+
continue;
141+
}
142+
n = nn + v;
133143
}
134144

135145
Return:

0 commit comments

Comments
 (0)