Skip to content

Commit e0ae552

Browse files
com: fix loop/crash in dpvsnprintf() error handling
Somehow I didn't notice Sys_Printf() calls dpvsnprintf(), see 21fa901. Also fixes a minor bug where Sys_Print() could output more bytes than it should, introduced in 01642af. Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
1 parent ffc8287 commit e0ae552

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

common.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,12 +1018,27 @@ int dpvsnprintf (char *buffer, size_t buffersize, const char *format, va_list ar
10181018
#endif
10191019
if (result < 0 || (size_t)result >= buffersize)
10201020
{
1021-
buffer[buffersize - 1] = '\0';
1022-
// we could be inside Con_Printf
1021+
// _vsnprintf_s returns -1 on error and on truncation (indistinguishable),
1022+
// vsnprintf returns negative on error and the desired strlen on truncation.
1023+
buffer[buffersize - 1] = '\0'; // should be unnecessary, but just in case
1024+
// Basic stdout only: we could be inside Con_Printf, Sys_Printf calls dpvsnprintf,
1025+
// Windows console doesn't support colours.
10231026
if (result < 0)
1024-
Sys_Printf("dpvsnprintf: output error, buffer size %lu\n", (unsigned long)buffersize);
1027+
Sys_Print("dpvsnprintf: output error!\n", 27);
10251028
else
1026-
Sys_Printf("dpvsnprintf: truncated to %lu bytes: \"%s\"\n", (unsigned long)buffersize - 1, buffer);
1029+
{
1030+
char msg[MAX_INPUTLINE];
1031+
#if _MSC_VER >= 1400
1032+
result = _snprintf_s(msg, sizeof(msg), _TRUNCATE, "dpvsnprintf: truncated to %lu bytes: \"%s\"\n", (unsigned long)buffersize - 1, buffer);
1033+
#else
1034+
result = snprintf(msg, sizeof(msg), "dpvsnprintf: truncated to %lu bytes: \"%s\"\n", (unsigned long)buffersize - 1, buffer);
1035+
#endif
1036+
if (result > 0)
1037+
{
1038+
msg[sizeof(msg) - 1] = '\n'; // may have been lost in truncation
1039+
Sys_Print(msg, min((size_t)result, sizeof(msg)));
1040+
}
1041+
}
10271042
return -1;
10281043
}
10291044

sys_shared.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,12 +629,13 @@ void Sys_Print(const char *text, size_t textlen)
629629
#else
630630
#define write _write
631631
#endif
632-
while(*text)
632+
while(*text && textlen)
633633
{
634634
fs_offset_t written = (fs_offset_t)write(sys.outfd, text, textlen);
635635
if(written <= 0)
636636
break; // sorry, I cannot do anything about this error - without an output
637637
text += written;
638+
textlen -= written;
638639
}
639640
#ifndef WIN32
640641
if (sys_stdout_blocks.integer)

0 commit comments

Comments
 (0)