Restart CI for New Technology and UBSAN hunting

Continuous Integration (via runit and runitd) is now re-enabled on win7
and win10. The `make test` command, which runs the tests on all systems
is now the fastest and most stable it's been since the project started.

UBSAN is now enabled in MODE=dbg in addition to ASAN. Many instances of
undefined behavior have been removed. Mostly things like passing a NULL
argument to memcpy(), which works fine with Cosmopolitan Libc, but that
doesn't prevents the compiler from being unhappy. There was an issue w/
GNU make where static analysis claims a sprintf() call can overflow. We
also now have nicer looking crash reports on Windows since uname should
now be supported and msys64 addr2line works reliably.
This commit is contained in:
Justine Tunney 2022-03-21 03:46:16 -07:00
parent d5ff2c3fb9
commit 5e8ae2d5bc
80 changed files with 506 additions and 249 deletions

View file

@ -872,7 +872,7 @@ file_timestamp_cons (const char *fname, time_t stamp, long int ns)
char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
const char *f = fname ? fname : _("Current time");
ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX;
file_timestamp_sprintf (buf, ts);
file_timestamp_sprintf (buf, sizeof(buf), ts);
OSS (error, NILF,
_("%s: Timestamp out of range; substituting %s"), f, buf);
}
@ -933,27 +933,37 @@ file_timestamp_now (int *resolution)
/* Place into the buffer P a printable representation of the file
timestamp TS. */
void
file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts)
file_timestamp_sprintf (char *p, int n, FILE_TIMESTAMP ts)
{
/*
* [jart] patch weakness upstream because buffer can probably overflow
* if integer timestamp is irreguular
*/
int m;
time_t t = FILE_TIMESTAMP_S (ts);
struct tm *tm = localtime (&t);
if (tm)
sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
snprintf (p, n, "%04d-%02d-%02d %02d:%02d:%02d",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
else if (t < 0)
sprintf (p, "%ld", (long) t);
snprintf (p, n, "%ld", (long) t);
else
sprintf (p, "%lu", (unsigned long) t);
p += strlen (p);
snprintf (p, n, "%lu", (unsigned long) t);
m = strlen (p);
p += m;
n -= m;
if (n <= 0) return;
/* Append nanoseconds as a fraction, but remove trailing zeros. We don't
know the actual timestamp resolution, since clock_getres applies only to
local times, whereas this timestamp might come from a remote filesystem.
So removing trailing zeros is the best guess that we can do. */
sprintf (p, ".%09d", FILE_TIMESTAMP_NS (ts));
p += strlen (p) - 1;
snprintf (p, n, ".%09d", FILE_TIMESTAMP_NS (ts));
m = strlen (p) - 1;
p += m;
n += m;
while (*p == '0')
p--;
p += *p != '.';
@ -1052,7 +1062,7 @@ print_file (const void *item)
else
{
char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
file_timestamp_sprintf (buf, f->last_mtime);
file_timestamp_sprintf (buf, sizeof(buf), f->last_mtime);
printf (_("# Last modified %s\n"), buf);
}
puts (f->updated

View file

@ -164,14 +164,14 @@ int stemlen_compare (const void *v1, const void *v2);
add 4 to allow for any 4-digit epoch year (e.g. 1970);
add 25 to allow for "-MM-DD HH:MM:SS.NNNNNNNNN". */
#define FLOOR_LOG2_SECONDS_PER_YEAR 24
#define FILE_TIMESTAMP_PRINT_LEN_BOUND \
#define FILE_TIMESTAMP_PRINT_LEN_BOUND /* 62 */ \
(((sizeof (FILE_TIMESTAMP) * CHAR_BIT - 1 - FLOOR_LOG2_SECONDS_PER_YEAR) \
* 302 / 1000) \
+ 1 + 1 + 4 + 25)
FILE_TIMESTAMP file_timestamp_cons (char const *, time_t, long int);
FILE_TIMESTAMP file_timestamp_now (int *);
void file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts);
void file_timestamp_sprintf (char *, int, FILE_TIMESTAMP );
/* Return the mtime of file F (a struct file *), caching it.
The value is NONEXISTENT_MTIME if the file does not exist. */