From 3ada0c8059b3250726b91ec3d0aaff484324174c Mon Sep 17 00:00:00 2001 From: Pepijn van der Stap Date: Sun, 1 Jun 2025 13:37:00 +0200 Subject: [PATCH] feat(dotter): Ensure null termination and robust buffer handling - Explicitly null-terminating the output strings in both slipstream_inline_dotify and slipstream_inline_undotify. - Improving the buffer size check in slipstream_inline_dotify to correctly account for the null terminator. - Enhancing the handling of empty input strings in slipstream_inline_dotify. --- src/slipstream_inline_dots.c | 44 ++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/slipstream_inline_dots.c b/src/slipstream_inline_dots.c index 83111e0..ecf776c 100644 --- a/src/slipstream_inline_dots.c +++ b/src/slipstream_inline_dots.c @@ -1,29 +1,35 @@ #include "slipstream_inline_dots.h" size_t slipstream_inline_dotify(char * __restrict__ buf, size_t buflen, size_t len) { - size_t dots = len / 57; // Number of dots to insert - size_t new_len = len + dots; - - // Check if result would exceed buffer - if (new_len > buflen) { - return -1; // Error condition + if (len == 0) { // If there's nothing to do, we do nothing. Efficient, right? + if (buflen > 0) buf[0] = '\0'; + return 0; } - // Start from the end and work backwards - char *src = buf + len - 1; // Points to last char of original string - char *dst = buf + new_len - 1; // Points to where last char will end up + size_t dots = len / 57; // Every 57 bytes, a dot. It's the law. + size_t new_len = len + dots; + + if (new_len + 1 > buflen) { + return (size_t)-1; // Err -> .h? Meh. + } + + buf[new_len] = '\0'; // Amen. + + char *src = buf + len - 1; // Points to last char of original string + char *dst = buf + new_len - 1; // Points to where last char will end up // Avoid modulo operation in tight loop size_t next_dot = len - (len % 57); + size_t current_pos = len; // Move characters right-to-left, inserting dots while (current_pos > 0) { if (current_pos == next_dot) { - *dst-- = '.'; - next_dot -= 57; - current_pos--; - continue; + *dst-- = '.'; // Dot. Because rules are rules, even for dots. + next_dot -= 57; // Next dot is 57 chars back. + current_pos--; // Account for the char space the dot took. + continue; // Skip the copy for this iteration, already placed dot. } *dst-- = *src--; current_pos--; @@ -36,14 +42,12 @@ size_t slipstream_inline_undotify(char * __restrict__ buf, size_t len) { char *reader = buf; char *writer = buf; - // For ~255 byte buffer with dots every ~50 chars - // Simple loop is most efficient since dots are sparse - while (len--) { + for (size_t i = 0; i < len; ++i) { char c = *reader++; - if (c != '.') { - *writer++ = c; - } + if (c != '.') + *writer++ = c; // Filter out the noise. Only the good stuff. } + *writer = '\0'; // Rewind the tape. The future is clean. return writer - buf; -} \ No newline at end of file +}