diff --git a/src/86box.c b/src/86box.c index 1c11d9bee..ae58aca03 100644 --- a/src/86box.c +++ b/src/86box.c @@ -782,7 +782,11 @@ usage: goto usage; temp2 = (char *) calloc(2048, 1); - sscanf(argv[++c], "%c:%s", &drive, temp2); + if (sscanf(argv[++c], "%c:%2047s", &drive, temp2) != 2) { + fprintf(stderr, "Invalid input format for --image option.\n"); + free(temp2); + goto usage; + } if (drive > 0x40) drive = (drive & 0x1f) - 1; else @@ -1021,9 +1025,21 @@ usage: * This is where we start outputting to the log file, * if there is one. Create a little info header first. */ + struct tm time_buf; + (void) time(&now); - info = localtime(&now); - strftime(temp, sizeof(temp), "%Y/%m/%d %H:%M:%S", info); +#ifdef _WIN32 + if (localtime_s(&time_buf, &now) == 0) + info = &time_buf; +#else + info = localtime_r(&now, &time_buf); +#endif + + if (info) + strftime(temp, sizeof(temp), "%Y/%m/%d %H:%M:%S", info); + else + strcpy(temp, "unknown"); + pclog("#\n# %ls v%ls logfile, created %s\n#\n", EMU_NAME_W, EMU_VERSION_FULL_W, temp); pclog("# VM: %s\n#\n", vm_name); diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index cf132c560..3eec6d5a1 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -446,24 +446,36 @@ static int viso_fill_time(uint8_t *data, time_t time, int format, int longform) { uint8_t *p = data; - struct tm *time_s = localtime(&time); - if (!time_s) { - /* localtime will return NULL if the time_t is negative (Windows) - or way too far into 64-bit space (Linux). Fall back to epoch. */ - time_t epoch = 0; - time_s = localtime(&epoch); - if (UNLIKELY(!time_s)) - fatal("VISO: localtime(0) = NULL\n"); + struct tm time_s_buf; + struct tm *time_s = NULL; + time_t epoch = 0; - /* Force year clamping if the timestamp is known to be outside the supported ranges. */ +#ifdef _WIN32 + if (localtime_s(&time_s_buf, &time) == 0) + time_s = &time_s_buf; +#else + time_s = localtime_r(&time, &time_s_buf); +#endif + + if (!time_s) { + /* localtime may return NULL if time is negative or out of range */ +#ifdef _WIN32 + if (localtime_s(&time_s_buf, &epoch) == 0) + time_s = &time_s_buf; +#else + time_s = localtime_r(&epoch, &time_s_buf); +#endif + if (!time_s) + fatal("VISO: localtime fallback to epoch failed\n"); + + /* Force year clamping for out-of-range times */ if (time < (longform ? -62135596800LL : -2208988800LL)) /* 0001-01-01 00:00:00 : 1900-01-01 00:00:00 */ time_s->tm_year = -1901; else if (time > (longform ? 253402300799LL : 5869583999LL)) /* 9999-12-31 23:59:59 : 2155-12-31 23:59:59 */ time_s->tm_year = 8100; } - /* Clamp year to the supported ranges, and assume the - OS returns valid numbers in the other struct fields. */ + /* Clamp year within supported ranges */ if (time_s->tm_year < (longform ? -1900 : 0)) { time_s->tm_year = longform ? -1900 : 0; time_s->tm_mon = time_s->tm_hour = time_s->tm_min = time_s->tm_sec = 0; @@ -476,18 +488,18 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform) time_s->tm_min = time_s->tm_sec = 59; } - /* Convert timestamp. */ + /* Convert timestamp */ if (longform) { - p += sprintf((char *) p, "%04u%02u%02u%02u%02u%02u00", - 1900 + time_s->tm_year, 1 + time_s->tm_mon, time_s->tm_mday, + p += sprintf((char *)p, "%04u%02u%02u%02u%02u%02u00", + 1900 + (unsigned)time_s->tm_year, 1 + time_s->tm_mon, time_s->tm_mday, time_s->tm_hour, time_s->tm_min, time_s->tm_sec); } else { - *p++ = time_s->tm_year; /* year since 1900 */ - *p++ = 1 + time_s->tm_mon; /* month */ - *p++ = time_s->tm_mday; /* day */ - *p++ = time_s->tm_hour; /* hour */ - *p++ = time_s->tm_min; /* minute */ - *p++ = time_s->tm_sec; /* second */ + *p++ = (uint8_t)time_s->tm_year; /* year since 1900 */ + *p++ = (uint8_t)(1 + time_s->tm_mon); /* month */ + *p++ = (uint8_t)time_s->tm_mday; /* day */ + *p++ = (uint8_t)time_s->tm_hour; /* hour */ + *p++ = (uint8_t)time_s->tm_min; /* minute */ + *p++ = (uint8_t)time_s->tm_sec; /* second */ } if (format & VISO_FORMAT_ISO) *p++ = tz_offset; /* timezone (ISO only) */ @@ -1034,8 +1046,15 @@ next_dir: the timezone offset for descriptors and file times to use. */ tzset(); time_t now = time(NULL); - if (viso->format & VISO_FORMAT_ISO) /* timezones are ISO only */ - tz_offset = (now - mktime(gmtime(&now))) / (3600 / 4); + struct tm now_tm; + if (viso->format & VISO_FORMAT_ISO) { /* timezones are ISO only */ +#ifdef _WIN32 + gmtime_s(&now_tm, &now); // Windows: output first param, input second +#else + gmtime_r(&now, &now_tm); // POSIX: input first param, output second +#endif + tz_offset = (now - mktime(&now_tm)) / (3600 / 4); + } /* Get root directory basename for the volume ID. */ const char *basename = path_get_filename(viso->root_dir->path); diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 5113ca817..73626acd2 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -264,6 +264,7 @@ opVPCEXT(uint32_t fetchdat) uint8_t b2; uint16_t cent; time_t now; + struct tm tm_buf; struct tm *tm = NULL; if (!is_vpc) /* only emulate this on Virtual PC machines */ @@ -282,7 +283,16 @@ opVPCEXT(uint32_t fetchdat) /* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */ if (b1 == 0x03) { (void) time(&now); - tm = localtime(&now); + +#ifdef _WIN32 + if (localtime_s(&tm_buf, &now) == 0) + tm = &tm_buf; +#else + tm = localtime_r(&now, &tm_buf); +#endif + + if (!tm) + fatal("localtime() failed for host clock\n"); } if ((b1 == 0x07) && (b2 == 0x0b)) { diff --git a/src/nvr.c b/src/nvr.c index 7f43a76c1..b6bf2a5a5 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -310,18 +310,25 @@ nvr_close(void) void nvr_time_sync(void) { - struct tm *tm; - time_t now; + struct tm tm; + time_t now; /* Get the current time of day, and convert to local time. */ (void) time(&now); - if (time_sync & TIME_SYNC_UTC) - tm = gmtime(&now); - else - tm = localtime(&now); - /* Set the internal clock. */ - nvr_time_set(tm); +#ifdef _WIN32 + if (time_sync & TIME_SYNC_UTC) + gmtime_s(&tm, &now); + else + localtime_s(&tm, &now); +#else + if (time_sync & TIME_SYNC_UTC) + gmtime_r(&now, &tm); + else + localtime_r(&now, &tm); +#endif + + nvr_time_set(&tm); } /* Get current time from internal clock. */ diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 8c2586482..8677a6a91 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -341,9 +341,25 @@ path_get_slash(char *path) void path_append_filename(char *dest, const char *s1, const char *s2) { - strcpy(dest, s1); - path_slash(dest); - strcat(dest, s2); + size_t dest_size = 260; + size_t len; + + if (!dest || !s1 || !s2) + return; + + snprintf(dest, dest_size, "%s", s1); + len = strlen(dest); + + if (len > 0 && dest[len - 1] != '/' && dest[len - 1] != '\\') { + if (len + 1 < dest_size) { + dest[len++] = '/'; + dest[len] = '\0'; + } + } + + if (len < dest_size - 1) { + strncat(dest, s2, dest_size - len - 1); + } } void diff --git a/src/utils/log.c b/src/utils/log.c index 257029b51..f10dff56b 100644 --- a/src/utils/log.c +++ b/src/utils/log.c @@ -106,7 +106,6 @@ log_out(void *priv, const char *fmt, va_list ap) { log_t *log = (log_t *) priv; char temp[1024]; - char fmt2[1024]; if (log == NULL) pclog("WARNING: Logging called with a NULL log pointer\n"); @@ -115,18 +114,20 @@ log_out(void *priv, const char *fmt, va_list ap) else if (fmt[0] != '\0') { log_ensure_stdlog_open(); - vsprintf(temp, fmt, ap); + vsnprintf(temp, sizeof(temp), fmt, ap); + if (log->suppr_seen && !strcmp(log->buff, temp)) log->seen++; else { if (log->suppr_seen && log->seen) { - log_copy(log, fmt2, "*** %d repeats ***\n", 1024); - fprintf(stdlog, fmt2, log->seen); + fprintf(stdlog, "*** %d repeats ***\n", log->seen); } log->seen = 0; - strcpy(log->buff, temp); - log_copy(log, fmt2, temp, 1024); - fprintf(stdlog, fmt2, ap); + + strncpy(log->buff, temp, sizeof(log->buff) - 1); + log->buff[sizeof(log->buff) - 1] = '\0'; + + fprintf(stdlog, "%s", temp); } fflush(stdlog);