diff options
author | Ben Wiederhake <BenWiederhake.GitHub@gmx.de> | 2020-08-16 01:37:32 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-22 20:55:10 +0200 |
commit | 0240baa42de554a7eb103020c2d53373d3468b31 (patch) | |
tree | 1c8d20eb3484ed1f7eff060e3b2a41f42bc9435f | |
parent | 2d34f0f93a89e5e7ca10133a0be2ec09548babea (diff) | |
download | serenity-0240baa42de554a7eb103020c2d53373d3468b31.zip |
AK+Kernel: Support snprintf
In contrast to sprintf, which might overflow the given buffer.
I feel bad about the code duplication, but that is a pre-existing issue.
-rw-r--r-- | AK/kstdio.h | 1 | ||||
-rw-r--r-- | Kernel/kprintf.cpp | 28 | ||||
-rw-r--r-- | Kernel/kstdio.h | 1 |
3 files changed, 30 insertions, 0 deletions
diff --git a/AK/kstdio.h b/AK/kstdio.h index 78ca52bc9a..98f69caeb2 100644 --- a/AK/kstdio.h +++ b/AK/kstdio.h @@ -37,6 +37,7 @@ int vdbgprintf(const char* fmt, va_list); int dbgprintf(const char* fmt, ...); ssize_t dbgputstr(const char*, ssize_t); int sprintf(char* buf, const char* fmt, ...); +int snprintf(char* buffer, size_t, const char* fmt, ...); } # endif #else diff --git a/Kernel/kprintf.cpp b/Kernel/kprintf.cpp index 3e2eff5b04..6834ce00bd 100644 --- a/Kernel/kprintf.cpp +++ b/Kernel/kprintf.cpp @@ -144,6 +144,34 @@ int sprintf(char* buffer, const char* fmt, ...) return ret; } +static size_t __vsnprintf_space_remaining; +ALWAYS_INLINE void sized_buffer_putch(char*& bufptr, char ch) +{ + if (__vsnprintf_space_remaining) { + *bufptr++ = ch; + --__vsnprintf_space_remaining; + } +} + +int snprintf(char* buffer, size_t size, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (size) { + __vsnprintf_space_remaining = size - 1; + } else { + __vsnprintf_space_remaining = 0; + } + int ret = printf_internal(sized_buffer_putch, buffer, fmt, ap); + if (__vsnprintf_space_remaining) { + buffer[ret] = '\0'; + } else if (size > 0) { + buffer[size - 1] = '\0'; + } + va_end(ap); + return ret; +} + static void debugger_out(char ch) { if (serial_debug) diff --git a/Kernel/kstdio.h b/Kernel/kstdio.h index b6f3d17cf9..32f3b1adda 100644 --- a/Kernel/kstdio.h +++ b/Kernel/kstdio.h @@ -34,6 +34,7 @@ int dbgputstr(const char*, int); int kernelputstr(const char*, int); int kprintf(const char* fmt, ...); int sprintf(char* buf, const char* fmt, ...); +int snprintf(char* buf, size_t, const char* fmt, ...); void set_serial_debug(bool on_or_off); int get_serial_debug(); } |