diff options
author | 2025-06-27 12:16:04 +0300 | |
---|---|---|
committer | 2025-06-27 16:18:29 +0200 | |
commit | 8d0563380db8f3412de1fabf5ad74ccde1159eac (patch) | |
tree | 19204b6810e361a6c530d7e720b7c018485445e6 /src | |
parent | 8061f08b4e0a8f0ab5d1548b7e9978f3cc8647a2 (diff) | |
download | idevicerestore-8d0563380db8f3412de1fabf5ad74ccde1159eac.tar.gz idevicerestore-8d0563380db8f3412de1fabf5ad74ccde1159eac.tar.bz2 |
Improve type safety of new logging system and its handling of varargs
- Replaced loglevel arguments and globals using the `int` type with the `loglevel` enum.
- Moved logging print func handler function declaration to typedef.
- Fixed misuse of `print_func` where a char* was passed in place of `va_list` via a wrapper function `print_funcf`.
- Fixed reuse of varargs in `logger` causing a segfault when `stderr_enabled` is true.
- Fixed length in `snprintf` call inside `logger_hex_dump` truncating the printed text.
Diffstat (limited to 'src')
-rw-r--r-- | src/idevicerestore.c | 4 | ||||
-rw-r--r-- | src/log.c | 26 | ||||
-rw-r--r-- | src/log.h | 6 |
3 files changed, 25 insertions, 11 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 3dd4bb9..f4ced47 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -1744,7 +1744,7 @@ static void plain_progress_func(struct progress_info_entry** progress_info, int } } -static void tty_print(int level, const char* format, va_list varglist) +static void tty_print(enum loglevel level, const char* fmt, va_list ap) { switch (level) { case 0: @@ -1760,7 +1760,7 @@ static void tty_print(int level, const char* format, va_list varglist) break; } - cvfprintf(stdout, format, varglist); + cvfprintf(stdout, fmt, ap); cprintf(COLOR_RESET); } @@ -41,10 +41,10 @@ static int stderr_enabled = 1; -int log_level = LL_VERBOSE; -int print_level = LL_INFO; +enum loglevel log_level = LL_VERBOSE; +enum loglevel print_level = LL_INFO; -static void (*print_func)(int level, const char* fmt, va_list) = NULL; +static logger_print_func print_func = NULL; const char *_level_label[6] = { " <Error>", @@ -98,6 +98,7 @@ INITIALIZER(logger_init) void logger(enum loglevel level, const char *fmt, ...) { va_list ap; + va_list ap2; char *fs; if (level > log_level) @@ -129,6 +130,7 @@ void logger(enum loglevel level, const char *fmt, ...) #endif va_start(ap, fmt); + va_copy(ap2, ap); if (print_func) { if (stderr_enabled) { vfprintf(stderr, fs, ap); @@ -136,19 +138,29 @@ void logger(enum loglevel level, const char *fmt, ...) } if (level <= print_level) { // skip the timestamp and log level string - print_func(level, fs+23, ap); + print_func(level, fs+23, ap2); } } else { vprintf(fs, ap); } va_end(ap); + va_end(ap2); free(fs); mutex_unlock(&log_mutex); } +static void print_funcf(enum loglevel level, const char* fmt, ...) __attribute__ ((format (printf, 2, 3))); +static void print_funcf(enum loglevel level, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + print_func(level, fmt, ap); + va_end(ap); +} + void logger_dump_hex(enum loglevel level, const void* buf, unsigned int len) { char *fs; @@ -160,7 +172,7 @@ void logger_dump_hex(enum loglevel level, const void* buf, unsigned int len) fs = (char*)malloc(len * 3 + 1); for (unsigned int i = 0; i < len; i++) { - snprintf(fs + i*3, 3, "%02x%c", ((unsigned char*)buf)[i], (i < len-1) ? ' ' : '\n'); + snprintf(fs + i*3, 4, "%02x%c", ((unsigned char*)buf)[i], (i < len-1) ? ' ' : '\n'); } if (print_func) { if (stderr_enabled) { @@ -168,7 +180,7 @@ void logger_dump_hex(enum loglevel level, const void* buf, unsigned int len) fflush(stderr); } if (level <= print_level) { - print_func(level, "%s", fs); + print_funcf(level, "%s", fs); } } else { printf("%s", fs); @@ -204,7 +216,7 @@ int logger_set_logfile(const char* path) return 0; } -void logger_set_print_func(void (*func)(int, const char*, va_list)) +void logger_set_print_func(logger_print_func func) { print_func = func; } @@ -30,11 +30,13 @@ enum loglevel { LL_DEBUG }; -extern int log_level; +extern enum loglevel log_level; + +typedef void (*logger_print_func)(enum loglevel level, const char*, va_list); void logger(enum loglevel level, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); int logger_set_logfile(const char* path); -void logger_set_print_func(void (*func)(int level, const char*, va_list)); +void logger_set_print_func(logger_print_func func); void logger_dump_hex(enum loglevel level, const void* buf, unsigned int len); void logger_dump_plist(enum loglevel level, plist_t plist, int human_readable); |