Description
When compiling libarchive with the compile flag -fsanitize=undefined (enabling undefined behaviour sanitizer) it'll throw a warning when trying to open any mtree file:
libarchive/archive_read_support_format_mtree.c:146:10: runtime error: signed integer overflow: 9223372036854775807 * 2 cannot be represented in type 'long int'
libarchive/archive_read_support_format_mtree.c:168:6: runtime error: signed integer overflow: -9223372036854775808 * 2 cannot be represented in type 'long int'
This is the code that's causing this:
static int64_t
get_time_t_max(void)
{
if defined(TIME_T_MAX)
return TIME_T_MAX;
else
static time_t t;
time_t a;
if (t == 0) {
a = 1;
while (a > t) {
t = a;
a = a * 2 + 1;
}
}
return t;
endif
}
static int64_t
get_time_t_min(void)
{
if defined(TIME_T_MIN)
return TIME_T_MIN;
else
/* 't' will hold the minimum value, which will be zero (if
* time_t is unsigned) or -2^n (if time_t is signed). */
static int computed;
static time_t t;
time_t a;
if (computed == 0) {
a = (time_t)-1;
while (a < t) {
t = a;
a = a * 2;
}
computed = 1;
}
return t;
endif
}
What libarchive is trying to do here is calculating the value of TIME_T_MIN/MAX by triggering an overflow.
However overflows in signed values are undefined in C. This code is therefore strictly speaking invalid, the compiler may do whatever it likes in such situations, without any defined outcome.
I haven't come up with an elegant other way to do this yet. Probably the best would be to convince the glibc devs to define TIME_T_MIN/MAX in their headers.