From 23810c1a482bbd6cc51cba5b5c5ce7786fd4827b Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Tue, 1 Dec 2015 21:10:25 +0100 Subject: [PATCH] Fix snprintf(NULL, 0, ...) undefined behavior. --- libc/stdio/snprintf.cpp | 2 +- libc/stdio/sprintf.cpp | 2 +- libc/stdio/vsnprintf.cpp | 38 ++++++++++++++++++-------------------- libc/stdio/vsprintf.cpp | 2 +- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/libc/stdio/snprintf.cpp b/libc/stdio/snprintf.cpp index eba42fbb..d0ed7847 100644 --- a/libc/stdio/snprintf.cpp +++ b/libc/stdio/snprintf.cpp @@ -18,7 +18,7 @@ along with the Sortix C Library. If not, see . stdio/snprintf.cpp - Prints a formatted string to a limited string. + Prints a formatted string to the supplied buffer. *******************************************************************************/ diff --git a/libc/stdio/sprintf.cpp b/libc/stdio/sprintf.cpp index fd9cc5d7..046c86fe 100644 --- a/libc/stdio/sprintf.cpp +++ b/libc/stdio/sprintf.cpp @@ -18,7 +18,7 @@ along with the Sortix C Library. If not, see . stdio/sprintf.cpp - Prints a formatted string to a string. + Prints a formatted string to the supplied buffer. *******************************************************************************/ diff --git a/libc/stdio/vsnprintf.cpp b/libc/stdio/vsnprintf.cpp index ac654d55..c75ab63f 100644 --- a/libc/stdio/vsnprintf.cpp +++ b/libc/stdio/vsnprintf.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015. This file is part of the Sortix C Library. @@ -18,7 +18,7 @@ along with the Sortix C Library. If not, see . stdio/vsnprintf.cpp - Prints a formatted string to a limited string. + Prints a formatted string to the supplied buffer. *******************************************************************************/ @@ -26,40 +26,38 @@ #include #include -typedef struct vsnprintf_struct +struct vsnprintf { char* str; size_t size; - size_t produced; size_t written; -} vsnprintf_t; +}; -static size_t StringPrintCallback(void* user, const char* string, - size_t stringlen) +static size_t vsnprintf_callback(void* ctx, const char* string, size_t length) { - vsnprintf_t* info = (vsnprintf_t*) user; - if ( info->produced < info->size ) + struct vsnprintf* info = (struct vsnprintf*) ctx; + if ( 1 <= info->size && info->written < info->size ) { - size_t available = info->size - info->produced; - size_t possible = (stringlen < available) ? stringlen : available; - memcpy(info->str + info->produced, string, possible); + size_t available = info->size - info->written; + size_t possible = length < available ? length : available; + memcpy(info->str + info->written, string, possible); info->written += possible; } - info->produced += stringlen; - return stringlen; + return length; } extern "C" -int vsnprintf(char* restrict str, size_t size, const char* restrict format, +int vsnprintf(char* restrict str, + size_t size, + const char* restrict format, va_list list) { - vsnprintf_t info; + struct vsnprintf info; info.str = str; - info.size = size ? size-1 : 0; - info.produced = 0; + info.size = size ? size - 1 : 0; info.written = 0; - int result = vcbprintf(&info, StringPrintCallback, format, list); - if ( size ) + int result = vcbprintf(&info, vsnprintf_callback, format, list); + if ( 1 <= size ) info.str[info.written] = '\0'; return result; } diff --git a/libc/stdio/vsprintf.cpp b/libc/stdio/vsprintf.cpp index 2e1b39ab..8fc07b2d 100644 --- a/libc/stdio/vsprintf.cpp +++ b/libc/stdio/vsprintf.cpp @@ -18,7 +18,7 @@ along with the Sortix C Library. If not, see . stdio/vsprintf.cpp - Prints a formatted string to a string. + Prints a formatted string to the supplied buffer. *******************************************************************************/