btstack_util: add safe versions of snprintf

This commit is contained in:
Matthias Ringwald 2024-09-24 11:16:40 +02:00
parent 833cb08dda
commit ad144fa1bd
2 changed files with 83 additions and 5 deletions

View File

@ -45,16 +45,14 @@
#include "btstack_debug.h"
#include "btstack_util.h"
#include <stdio.h> // vsnprintf
#include <string.h> // memcpy
#ifdef _MSC_VER
#include <intrin.h>
#include <windows.h>
#endif
#ifdef ENABLE_PRINTF_HEXDUMP
#include <stdio.h>
#endif
#include <string.h>
/**
* @brief Compare two Bluetooth addresses
@ -641,6 +639,42 @@ void btstack_strcat(char * dst, uint16_t dst_size, const char * src){
dst[dst_len + bytes_to_copy] = 0;
}
int btstack_printf_strlen(const char * format, ...){
va_list argptr;
va_start(argptr, format);
char dummy_buffer[1];
int len = vsnprintf(dummy_buffer, sizeof(dummy_buffer), format, argptr);
va_end(argptr);
return len;
}
uint16_t btstack_snprintf_assert_complete(char * buffer, size_t size, const char * format, ...){
va_list argptr;
va_start(argptr, format);
int len = vsnprintf(buffer, size, format, argptr);
va_end(argptr);
// check for no error and no truncation
btstack_assert(len >= 0);
btstack_assert(len < size);
return (uint16_t) len;
}
uint16_t btstack_snprintf_best_effort(char * buffer, size_t size, const char * format, ...){
btstack_assert(size > 0);
va_list argptr;
va_start(argptr, format);
int len = vsnprintf(buffer, size, format, argptr);
va_end(argptr);
if (len < 0) {
// error -> len = 0
return 0;
} else {
// min of total string len and buffer size
return (uint16_t) btstack_min((uint32_t) len, (uint32_t) size - 1);
}
}
uint16_t btstack_virtual_memcpy(
const uint8_t * field_data, uint16_t field_len, uint16_t field_offset, // position of field in complete data block
uint8_t * buffer, uint16_t buffer_size, uint16_t buffer_offset){

View File

@ -377,6 +377,50 @@ uint16_t btstack_strcpy(char * dst, uint16_t dst_size, const char * src);
*/
void btstack_strcat(char * dst, uint16_t dst_size, const char * src);
/**
* @brief Calculated the number of characters that would get printed
* @note same as calling snprintf without a buffer
* @param format
* @param argsq
* @return number of characters, or negative value on error
*/
int btstack_printf_strlen(const char * format, ...)
#ifdef __GNUC__
__attribute__ ((format (__printf__, 1, 2)))
#endif
;
/**
* @brief Format string into buffer with '\0' and assert it is large enough
* @note same as calling snprintf and assert that the string was not truncated
* @param buffer
* @param size of buffer
* @param format
* @param argsq
* @return number of characters
*/
uint16_t btstack_snprintf_assert_complete(char * buffer, size_t size, const char * format, ...)
#ifdef __GNUC__
__attribute__ ((format (__printf__, 3, 4)))
#endif
;
/**
* @brief Format string into buffer, truncated if necessary. Output string is '\0' terminated
* @note similar to calling snprintf but returns the length of the output string
* @param buffer
* @param size of buffer
* @param format
* @param argsq
* @return number of characters
*/
uint16_t btstack_snprintf_best_effort(char * buffer, size_t size, const char * format, ...)
#ifdef __GNUC__
__attribute__ ((format (__printf__, 3, 4)))
#endif
;
/**
* Returns the number of leading 0-bits in x, starting at the most significant bit position.
* If x is 0, the result is undefined.