Fixed compilation error in basalt_logger where it whined about or'ing together two enum values for the log level.

Fixed a compilation error where the log level mask was being shadowed by log level index in basalt_log and basalt_write.
Fixed a bug where logger_add_stream was checking the lower 48-bits of the FILE* rather than the upper 16 were zero.
Fixed a bug where logger_add_stream did not mark a stream as allocated in its flags.
Fixed a bug where logger_remove_stream did not check if a stream was allocated.
Addressed warnings of potential saftey issues when logging the prefixes as if they were format strings by having them be format-specified. I suspect this is marginally slower and realistically had no security risk in the first place but was fixed anyway.
This commit is contained in:
2025-06-23 00:41:41 +10:00
parent f07977ff06
commit 87f66e291b
2 changed files with 19 additions and 15 deletions

View File

@@ -7,7 +7,8 @@
#define BASALT_LOGGER_MAX_STREAMS 7 #define BASALT_LOGGER_MAX_STREAMS 7
#endif #endif
typedef enum LOG_LEVEL { typedef u8 LOG_LEVEL;
typedef enum LOG_LEVELS {
LOG_FATAL = 1, LOG_FATAL = 1,
LOG_ERROR = 2, LOG_ERROR = 2,
LOG_WARN = 4, LOG_WARN = 4,
@@ -22,8 +23,9 @@ typedef enum LOG_LEVEL {
LOG_MASK_INFO = LOG_WARN | LOG_INFO | LOG_OK, LOG_MASK_INFO = LOG_WARN | LOG_INFO | LOG_OK,
LOG_MASK_ALL = LOG_MASK_ERRORS | LOG_MASK_DEBUGGING | LOG_MASK_INFO, LOG_MASK_ALL = LOG_MASK_ERRORS | LOG_MASK_DEBUGGING | LOG_MASK_INFO,
LOG_MASK_DEFAULT = LOG_MASK_ERRORS | LOG_MASK_INFO, LOG_MASK_DEFAULT = LOG_MASK_ERRORS | LOG_MASK_INFO,
} LOG_LEVEL; } LOG_LEVELS;
typedef u8 LOG_STREAM_FLAG;
typedef enum LOG_STREAM_FLAGS { typedef enum LOG_STREAM_FLAGS {
// Ignore this flag - it is internal to the library // Ignore this flag - it is internal to the library
LOG_STREAM_FLAG_INTERNAL_ALLOCATED_BIT = 1, LOG_STREAM_FLAG_INTERNAL_ALLOCATED_BIT = 1,
@@ -42,7 +44,7 @@ void initialize_logger();
void terminate_logger (); void terminate_logger ();
FILE* logger_stream_get_file(logger_stream_t* state); FILE* logger_stream_get_file(logger_stream_t* state);
u8 logger_add_stream(FILE* output, LOG_LEVEL mask, LOG_STREAM_FLAGS flags); u8 logger_add_stream(FILE* output, LOG_LEVEL mask, LOG_STREAM_FLAG flags);
void logger_remove_stream(u8 index); void logger_remove_stream(u8 index);
u8 logger_find_stream(FILE* target); u8 logger_find_stream(FILE* target);

View File

@@ -43,18 +43,18 @@ inline FILE* logger_stream_get_file(logger_stream_t* state)
return (FILE*)((state->stream & 0xffffffffffff) | ((u64)stdout & 0xffff0000000000)); return (FILE*)((state->stream & 0xffffffffffff) | ((u64)stdout & 0xffff0000000000));
} }
u8 logger_add_stream(FILE* output, LOG_LEVEL mask, LOG_STREAM_FLAGS flags) u8 logger_add_stream(FILE* output, LOG_LEVEL mask, LOG_STREAM_FLAG flags)
{ {
if (logger_state.num_streams == BASALT_LOGGER_MAX_STREAMS) if (logger_state.num_streams == BASALT_LOGGER_MAX_STREAMS)
return -1; return -1;
if ((((u64)output) & 0xffffffffffff) != 0) if ((((u64)output) & (~0xffffffffffff)) != 0)
__builtin_trap(); __builtin_trap();
for (u8 i = 0; i < BASALT_LOGGER_MAX_STREAMS; ++i) for (u8 i = 0; i < BASALT_LOGGER_MAX_STREAMS; ++i)
{ {
if ((logger_state.streams[i].flags & LOG_STREAM_FLAG_INTERNAL_ALLOCATED_BIT) == 0) if ((logger_state.streams[i].flags & LOG_STREAM_FLAG_INTERNAL_ALLOCATED_BIT) == 0)
{ {
logger_state.streams[i].stream = (u64)output; logger_state.streams[i].stream = (u64)output;
logger_state.streams[i].flags = flags; logger_state.streams[i].flags = flags | LOG_STREAM_FLAG_INTERNAL_ALLOCATED_BIT;
logger_state.streams[i].mask = mask; logger_state.streams[i].mask = mask;
logger_state.num_streams++; logger_state.num_streams++;
return i; return i;
@@ -68,6 +68,8 @@ void logger_remove_stream(u8 index)
if (index >= sizeof(logger_state.streams) / sizeof(logger_state.streams[0])) if (index >= sizeof(logger_state.streams) / sizeof(logger_state.streams[0]))
return; return;
logger_stream_t* stream = logger_state.streams+index; logger_stream_t* stream = logger_state.streams+index;
if ((stream->flags & LOG_STREAM_FLAG_INTERNAL_ALLOCATED_BIT) == 0)
return;
FILE* f = logger_stream_get_file(stream); FILE* f = logger_stream_get_file(stream);
if (f != stdout && f != stderr) if (f != stdout && f != stderr)
fclose(f); fclose(f);
@@ -94,8 +96,8 @@ void basalt_log(const LOG_LEVEL level, const char* msg, ...)
const char* log_ansi_prefixes[8] = { "\033[38;5;0m\033[48;5;9m", "\033[38;5;9m", "\033[38;5;11m", "\033[38;5;15m", "\033[38;5;10m", "\033[38;5;13m", "\033[38;5;12m", "\033[38;5;6m" }; const char* log_ansi_prefixes[8] = { "\033[38;5;0m\033[48;5;9m", "\033[38;5;9m", "\033[38;5;11m", "\033[38;5;15m", "\033[38;5;10m", "\033[38;5;13m", "\033[38;5;12m", "\033[38;5;6m" };
if (level == 0) if (level == 0)
return; return;
const u8 level = (u8)__builtin_ctz(level); const u8 err_level = (u8)__builtin_ctz(level);
if (level > 8) if (err_level > 8)
{ {
debug_break(); debug_break();
return; return;
@@ -115,7 +117,7 @@ void basalt_log(const LOG_LEVEL level, const char* msg, ...)
continue; continue;
FILE* out = logger_stream_get_file(stream); FILE* out = logger_stream_get_file(stream);
if (stream->flags & LOG_STREAM_FLAG_SUPPORTS_ANSI_BIT) if (stream->flags & LOG_STREAM_FLAG_SUPPORTS_ANSI_BIT)
fprintf(out, log_ansi_prefixes[level]); fprintf(out, "%s", log_ansi_prefixes[err_level]);
if ((stream->flags & LOG_STREAM_FLAG_DISABLE_PREFIXES) == 0) if ((stream->flags & LOG_STREAM_FLAG_DISABLE_PREFIXES) == 0)
{ {
if (stream->flags & LOG_STREAM_FLAG_INCLUDE_DATETIME_BIT) if (stream->flags & LOG_STREAM_FLAG_INCLUDE_DATETIME_BIT)
@@ -127,13 +129,13 @@ void basalt_log(const LOG_LEVEL level, const char* msg, ...)
if (!err) if (!err)
{ {
int n_chars = (int)strftime(time_buffer, sizeof(time_buffer), "%d-%m-%y %R:%S", &tm_info); int n_chars = (int)strftime(time_buffer, sizeof(time_buffer), "%d-%m-%y %R:%S", &tm_info);
fprintf(out, "[%*s %*s]: ", sizeof(log_prefixes[0]), log_prefixes[level], n_chars, time_buffer); fprintf(out, "[%*s %*s]: ", (int)sizeof(log_prefixes[0]), log_prefixes[err_level], n_chars, time_buffer);
} }
else else
fprintf(out, "[%*s]: ", sizeof(log_prefixes[0]), log_prefixes[level]); fprintf(out, "[%*s]: ", (int)sizeof(log_prefixes[0]), log_prefixes[err_level]);
} }
else else
fprintf(out, "[%*s]: ", sizeof(log_prefixes[0]), log_prefixes[level]); fprintf(out, "[%*s]: ", (int)sizeof(log_prefixes[0]), log_prefixes[err_level]);
} }
__builtin_va_list argstart; __builtin_va_list argstart;
va_start(argstart, msg); va_start(argstart, msg);
@@ -151,8 +153,8 @@ void basalt_write(const LOG_LEVEL level, const char* msg, ...)
const char* log_ansi_prefixes[8] = { "\033[38;5;0m\033[48;5;9m", "\033[38;5;9m", "\033[38;5;11m", "\033[38;5;15m", "\033[38;5;10m", "\033[38;5;13m", "\033[38;5;12m", "\033[38;5;6m" }; const char* log_ansi_prefixes[8] = { "\033[38;5;0m\033[48;5;9m", "\033[38;5;9m", "\033[38;5;11m", "\033[38;5;15m", "\033[38;5;10m", "\033[38;5;13m", "\033[38;5;12m", "\033[38;5;6m" };
if (level == 0) if (level == 0)
return; return;
const u8 level = (u8)__builtin_ctz(level); const u8 err_level = (u8)__builtin_ctz(level);
if (level > 8) if (err_level > 8)
{ {
debug_break(); debug_break();
return; return;
@@ -172,7 +174,7 @@ void basalt_write(const LOG_LEVEL level, const char* msg, ...)
continue; continue;
FILE* out = logger_stream_get_file(stream); FILE* out = logger_stream_get_file(stream);
if (stream->flags & LOG_STREAM_FLAG_SUPPORTS_ANSI_BIT) if (stream->flags & LOG_STREAM_FLAG_SUPPORTS_ANSI_BIT)
fprintf(out, log_ansi_prefixes[level]); fprintf(out, "%s", log_ansi_prefixes[err_level]);
__builtin_va_list argstart; __builtin_va_list argstart;
va_start(argstart, msg); va_start(argstart, msg);