summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Wiederhake <BenWiederhake.GitHub@gmx.de>2020-08-16 01:37:32 +0200
committerAndreas Kling <kling@serenityos.org>2020-08-22 20:55:10 +0200
commit0240baa42de554a7eb103020c2d53373d3468b31 (patch)
tree1c8d20eb3484ed1f7eff060e3b2a41f42bc9435f
parent2d34f0f93a89e5e7ca10133a0be2ec09548babea (diff)
downloadserenity-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.h1
-rw-r--r--Kernel/kprintf.cpp28
-rw-r--r--Kernel/kstdio.h1
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();
}