From 1406189511ac96ec0380f761063438f62bd51a5e Mon Sep 17 00:00:00 2001 From: Timerix Date: Mon, 10 Nov 2025 01:54:47 +0500 Subject: [PATCH] implemented buffer_size calculation in vsprintf_malloc --- include/tlibc/errors.h | 2 +- include/tlibc/string/cstr.h | 8 +++--- src/string/cstr.c | 56 ++++++++++++++++++++++--------------- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/include/tlibc/errors.h b/include/tlibc/errors.h index 0a26405..4fcc778 100755 --- a/include/tlibc/errors.h +++ b/include/tlibc/errors.h @@ -47,7 +47,7 @@ typedef struct Result_ { #define IGNORE_RESULT Result_ __ignored_##__LINE__ ATTRIBUTE_UNUSED = #define RESULT_ERROR(MSG, IS_MSG_ON_HEAP) (Result_){ .error = Error_create(MSG, IS_MSG_ON_HEAP, ErrorCallPos_here()) } -#define RESULT_ERROR_FMT(FORMAT, ARGS...) RESULT_ERROR(sprintf_malloc(4096, FORMAT ,##ARGS), true) +#define RESULT_ERROR_FMT(FORMAT, ARGS...) RESULT_ERROR(sprintf_malloc(FORMAT ,##ARGS), true) #define RESULT_ERROR_ERRNO() RESULT_ERROR(strerror(errno), false) #define RESULT_VOID (Result_){ .error = NULL, .u = 0 } #define RESULT_VALUE(FIELD, V) (Result_){ .error = NULL, .FIELD = V } diff --git a/include/tlibc/string/cstr.h b/include/tlibc/string/cstr.h index 1f62a5b..4712d39 100755 --- a/include/tlibc/string/cstr.h +++ b/include/tlibc/string/cstr.h @@ -2,8 +2,8 @@ #include "../std.h" #define strcat_malloc(STR0, ...) _strcat_malloc(count_args(__VA_ARGS__), STR0, __VA_ARGS__) -char* _strcat_malloc(size_t n, cstr str0, ...); -char* _vstrcat_malloc(size_t n, cstr str0, va_list argv); +char* _strcat_malloc(u64 n, cstr str0, ...); +char* _vstrcat_malloc(u64 n, cstr str0, va_list args); -char* NULLABLE(sprintf_malloc)(size_t buffer_size, cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(2, 3); -char* NULLABLE(vsprintf_malloc)(size_t buffer_size, cstr format, va_list argv); +char* sprintf_malloc(cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(1, 2); +char* vsprintf_malloc(cstr format, va_list args); diff --git a/src/string/cstr.c b/src/string/cstr.c index 2498adc..b8425a3 100755 --- a/src/string/cstr.c +++ b/src/string/cstr.c @@ -1,21 +1,21 @@ #include "tlibc/string/cstr.h" -char* _strcat_malloc(size_t n, cstr str0, ...){ - va_list argv; - va_start(argv, str0); - char* heap_ptr = _vstrcat_malloc(n, str0, argv); - va_end(argv); +char* _strcat_malloc(u64 n, cstr str0, ...){ + va_list args; + va_start(args, str0); + char* heap_ptr = _vstrcat_malloc(n, str0, args); + va_end(args); return heap_ptr; } -char* _vstrcat_malloc(size_t n, cstr str0, va_list argv){ - size_t str0_len = strlen(str0); - size_t total_len = str0_len; +char* _vstrcat_malloc(u64 n, cstr str0, va_list args){ + u64 str0_len = strlen(str0); + u64 total_len = str0_len; cstr* const parts = malloc(sizeof(cstr) * n); - size_t* const part_lengths = malloc(sizeof(size_t) * n); - for(size_t i = 0; i < n; i++){ - cstr part = va_arg(argv, cstr); - size_t length = strlen(part); + u64* const part_lengths = malloc(sizeof(u64) * n); + for(u64 i = 0; i < n; i++){ + cstr part = va_arg(args, cstr); + u64 length = strlen(part); parts[i] = part; part_lengths[i] = length; total_len += length; @@ -23,7 +23,7 @@ char* _vstrcat_malloc(size_t n, cstr str0, va_list argv){ char* const buf = malloc(total_len + 1); memcpy(buf, str0, str0_len); char* walking_ptr = buf + str0_len; - for(size_t i = 0; i < n; i++){ + for(u64 i = 0; i < n; i++){ memcpy(walking_ptr, parts[i], part_lengths[i]); walking_ptr += part_lengths[i]; } @@ -33,20 +33,30 @@ char* _vstrcat_malloc(size_t n, cstr str0, va_list argv){ return buf; } -char* NULLABLE(sprintf_malloc)(size_t buffer_size, cstr format, ...){ - va_list argv; - va_start(argv, format); - char* NULLABLE(heap_ptr) = vsprintf_malloc(buffer_size, format, argv); - va_end(argv); +char* NULLABLE(sprintf_malloc)(cstr format, ...){ + va_list args; + va_start(args, format); + char* heap_ptr = vsprintf_malloc(format, args); + va_end(args); return heap_ptr; } -char* NULLABLE(vsprintf_malloc)(size_t buffer_size, cstr format, va_list argv){ - char* buf = malloc(buffer_size); - int r = vsprintf(buf, format, argv); +char* vsprintf_malloc(cstr format, va_list args){ + // thanks to libtoml developer + va_list args_copy; + va_copy(args_copy, args); + i32 buf_size = vsnprintf(NULL, 0, format, args_copy); + va_end(args_copy); + + if(buf_size < 63) + buf_size = 63; + buf_size += 1; // for '\0' + char* buf = malloc(buf_size); + int r = vsnprintf(buf, buf_size, format, args); if(r < 0){ - free(buf); - return NULL; + char err_msg[] = ""; + u32 err_msg_size = sizeof(err_msg); + memcpy(buf, err_msg, err_msg_size); } return buf; }