From 9c656b7128905c3aa6703a622693fbbb4e3abec2 Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Mon, 7 Oct 2024 23:01:40 -0300 Subject: [PATCH] - Added `WUT_FORMAT_PRINTF` to catch format string errors in printf-like functions. - Fixed a few format string bugs, in `libwhb/crash.c` and `wutdevoptab`, where there was a mismatch of specifiers and arguments that could lead to crashes. - Made debug prints use `%p` when printing pointers. --HG-- branch : printf-attribute-hg --- include/coreinit/cosreport.h | 15 +++++++---- include/coreinit/debug.h | 15 +++++++---- include/coreinit/internal.h | 3 ++- include/wut.h | 26 ++++++++++--------- libraries/libgfd/src/gfd.c | 4 ++- libraries/libwhb/include/whb/log.h | 6 +++-- libraries/libwhb/src/crash.c | 12 ++++++--- libraries/libwhb/src/gfx_heap.c | 4 +-- libraries/wutdevoptab/devoptab_fsa.cpp | 4 +-- .../wutdevoptab/devoptab_fsa_dirnext.cpp | 2 +- .../wutdevoptab/devoptab_fsa_diropen.cpp | 2 +- libraries/wutdevoptab/devoptab_fsa_fstat.cpp | 5 ++-- libraries/wutdevoptab/devoptab_fsa_open.cpp | 8 +++--- libraries/wutdevoptab/devoptab_fsa_read.cpp | 4 +-- libraries/wutdevoptab/devoptab_fsa_seek.cpp | 2 +- libraries/wutdevoptab/devoptab_fsa_stat.cpp | 4 +-- .../wutdevoptab/devoptab_fsa_statvfs.cpp | 4 +-- .../wutdevoptab/devoptab_fsa_truncate.cpp | 2 +- libraries/wutdevoptab/devoptab_fsa_write.cpp | 2 +- 19 files changed, 73 insertions(+), 51 deletions(-) diff --git a/include/coreinit/cosreport.h b/include/coreinit/cosreport.h index b9547697b..4d90259ca 100644 --- a/include/coreinit/cosreport.h +++ b/include/coreinit/cosreport.h @@ -30,27 +30,32 @@ void COSVReport(COSReportModule module, COSReportLevel level, const char* fmt, - ...); + ...) + WUT_FORMAT_PRINTF(3, 4); void COSError(COSReportModule module, const char* fmt, - ...); + ...) + WUT_FORMAT_PRINTF(2, 3); void COSInfo(COSReportModule module, const char* fmt, - ...); + ...) + WUT_FORMAT_PRINTF(2, 3); void COSVerbose(COSReportModule module, const char* fmt, - ...); + ...) + WUT_FORMAT_PRINTF(2, 3); void COSWarn(COSReportModule module, const char* fmt, - ...); + ...) + WUT_FORMAT_PRINTF(2, 3); #ifdef __cplusplus } diff --git a/include/coreinit/debug.h b/include/coreinit/debug.h index 7a10b9063..58cb9aa93 100644 --- a/include/coreinit/debug.h +++ b/include/coreinit/debug.h @@ -30,25 +30,30 @@ __OSConsoleWrite(const char *msg, uint32_t size); void -OSReport(const char *fmt, ...); +OSReport(const char *fmt, ...) + WUT_FORMAT_PRINTF(1, 2); void -OSReportVerbose(const char *fmt, ...); +OSReportVerbose(const char *fmt, ...) + WUT_FORMAT_PRINTF(1, 2); void -OSReportInfo(const char *fmt, ...); +OSReportInfo(const char *fmt, ...) + WUT_FORMAT_PRINTF(1, 2); void -OSReportWarn(const char *fmt, ...); +OSReportWarn(const char *fmt, ...) + WUT_FORMAT_PRINTF(1, 2); void OSPanic(const char *file, uint32_t line, - const char *fmt, ...); + const char *fmt, ...) + WUT_FORMAT_PRINTF(3, 4); void diff --git a/include/coreinit/internal.h b/include/coreinit/internal.h index bd0f08731..3ff4a72c2 100644 --- a/include/coreinit/internal.h +++ b/include/coreinit/internal.h @@ -6,7 +6,8 @@ extern "C" { #endif int -__os_snprintf(char *buf, size_t n, const char *format, ... ); +__os_snprintf(char *buf, size_t n, const char *format, ... ) + WUT_FORMAT_PRINTF(3, 4); #ifdef __cplusplus } diff --git a/include/wut.h b/include/wut.h index b66fea3ca..469151231 100644 --- a/include/wut.h +++ b/include/wut.h @@ -6,25 +6,27 @@ * https://github.com/devkitPro/wut */ -#include "wut_structsize.h" -#include "wut_types.h" -#include "wut_rplwrap.h" -#ifdef DEBUG -#include -#endif +#if defined(__GNUC__) || defined(__clang__) -#ifdef __GNUC__ +#define WUT_DEPRECATED(reason) __attribute__((__deprecated__(reason))) +#define WUT_FORMAT_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args))) -#define WUT_DEPRECATED(reason) __attribute__((deprecated(reason))) - -#else // not __GNUC__ +#else // not __GNUC__ and not __clang__ #define WUT_DEPRECATED(reason) +#define WUT_FORMAT_PRINTF(fmt, args) -#endif //__GNUC__ +#endif //__GNUC__ or __clang__ #ifdef DEBUG #define WUT_DEBUG_REPORT(fmt, ...) OSReport(fmt, ##__VA_ARGS__) #else #define WUT_DEBUG_REPORT(fmt, ...) -#endif \ No newline at end of file +#endif + +#include "wut_structsize.h" +#include "wut_types.h" +#include "wut_rplwrap.h" +#ifdef DEBUG +#include +#endif diff --git a/libraries/libgfd/src/gfd.c b/libraries/libgfd/src/gfd.c index ab696d681..81f329cbe 100644 --- a/libraries/libgfd/src/gfd.c +++ b/libraries/libgfd/src/gfd.c @@ -35,7 +35,9 @@ static BOOL _GFDGetBlockPointer(GFDBlockType type, uint32_t index, void *file, static char sLastError[1024] = { 0 }; -static void +static +WUT_FORMAT_PRINTF(1, 2) +void setLastError(const char *fmt, ...) { va_list va; diff --git a/libraries/libwhb/include/whb/log.h b/libraries/libwhb/include/whb/log.h index f2c1964dd..08661267d 100644 --- a/libraries/libwhb/include/whb/log.h +++ b/libraries/libwhb/include/whb/log.h @@ -26,10 +26,12 @@ BOOL WHBLogPrint(const char *str); BOOL -WHBLogWritef(const char *fmt, ...); +WHBLogWritef(const char *fmt, ...) + WUT_FORMAT_PRINTF(1, 2); BOOL -WHBLogPrintf(const char *fmt, ...); +WHBLogPrintf(const char *fmt, ...) + WUT_FORMAT_PRINTF(1, 2); #ifdef __cplusplus } diff --git a/libraries/libwhb/src/crash.c b/libraries/libwhb/src/crash.c index f3cad2a1d..4c1e7e045 100644 --- a/libraries/libwhb/src/crash.c +++ b/libraries/libwhb/src/crash.c @@ -55,7 +55,9 @@ crashReportThread(int argc, const char **argv) return 0; } -static void +static +WUT_FORMAT_PRINTF(1, 2) +void disassemblyPrintCallback(const char* fmt, ...) { va_list args; @@ -124,7 +126,9 @@ getStackTrace(OSContext *context) sStackTraceBuffer[sStackTraceLength] = 0; } -static void +static +WUT_FORMAT_PRINTF(1, 2) +void writeRegister(const char* fmt, ...) { va_list args; @@ -185,8 +189,8 @@ getRegisters(OSContext *context) writeRegister("\n--GQRs----------\n"); for (i = 0; i < 4; ++i) { writeRegister("gqr%d = 0x%08x \t gqr%d = 0x%08x\n", - i, context->gqr[i], context->gqr[i], - i + 4, context->gqr[i + 4], context->gqr[i + 4]); + i, context->gqr[i], + i + 4, context->gqr[i + 4]); } writeRegister("\n--Per-core OSContext runtime ----\n"); diff --git a/libraries/libwhb/src/gfx_heap.c b/libraries/libwhb/src/gfx_heap.c index 8f8c71760..7e94128cd 100644 --- a/libraries/libwhb/src/gfx_heap.c +++ b/libraries/libwhb/src/gfx_heap.c @@ -39,7 +39,7 @@ GfxHeapInitMEM1() sGfxHeapMEM1 = MEMCreateExpHeapEx(base, size, 0); if (!sGfxHeapMEM1) { - WHBLogPrintf("%s: MEMCreateExpHeapEx(0x%08X, 0x%X, 0) failed", __FUNCTION__, base, size); + WHBLogPrintf("%s: MEMCreateExpHeapEx(%p, 0x%X, 0) failed", __FUNCTION__, base, size); return FALSE; } @@ -81,7 +81,7 @@ GfxHeapInitForeground() sGfxHeapForeground = MEMCreateExpHeapEx(base, size, 0); if (!sGfxHeapForeground) { - WHBLogPrintf("%s: MEMCreateExpHeapEx(0x%08X, 0x%X, 0)", __FUNCTION__, base, size); + WHBLogPrintf("%s: MEMCreateExpHeapEx(%p, 0x%X, 0)", __FUNCTION__, base, size); return FALSE; } diff --git a/libraries/wutdevoptab/devoptab_fsa.cpp b/libraries/wutdevoptab/devoptab_fsa.cpp index 15198bfe1..97bd9445a 100644 --- a/libraries/wutdevoptab/devoptab_fsa.cpp +++ b/libraries/wutdevoptab/devoptab_fsa.cpp @@ -67,8 +67,8 @@ FSError __init_wut_devoptab() { rc = FSAMount(__wut_fsa_device_data.clientHandle, "/dev/sdcard01", __wut_fsa_device_data.mountPath, (FSAMountFlags) 0, nullptr, 0); if (rc < 0 && rc != FS_ERROR_ALREADY_EXISTS) { - WUT_DEBUG_REPORT("FSAMount(0x%08X, \"/dev/sdcard01\", %s, %08X, %08X, %08X) failed: %s\n", - __wut_fsa_device_data.clientHandle, __wut_fsa_device_data.mountPath, 0, nullptr, 0, FSAGetStatusStr(rc)); + WUT_DEBUG_REPORT("FSAMount(0x%08X, \"/dev/sdcard01\", %s, 0, NULL, 0) failed: %s\n", + __wut_fsa_device_data.clientHandle, __wut_fsa_device_data.mountPath, FSAGetStatusStr(rc)); return rc; } diff --git a/libraries/wutdevoptab/devoptab_fsa_dirnext.cpp b/libraries/wutdevoptab/devoptab_fsa_dirnext.cpp index 6734b837d..14b8f9643 100644 --- a/libraries/wutdevoptab/devoptab_fsa_dirnext.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_dirnext.cpp @@ -25,7 +25,7 @@ __wut_fsa_dirnext(struct _reent *r, status = FSAReadDir(deviceData->clientHandle, dir->fd, &dir->entry_data); if (status < 0) { if (status != FS_ERROR_END_OF_DIR) { - WUT_DEBUG_REPORT("FSAReadDir(0x%08X, 0x%08X, 0x%08X) (%s) failed: %s\n", + WUT_DEBUG_REPORT("FSAReadDir(0x%08X, 0x%08X, %p) (%s) failed: %s\n", deviceData->clientHandle, dir->fd, &dir->entry_data, dir->fullPath, FSAGetStatusStr(status)); } r->_errno = __wut_fsa_translate_error(status); diff --git a/libraries/wutdevoptab/devoptab_fsa_diropen.cpp b/libraries/wutdevoptab/devoptab_fsa_diropen.cpp index d98babf9b..6cf073c72 100644 --- a/libraries/wutdevoptab/devoptab_fsa_diropen.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_diropen.cpp @@ -40,7 +40,7 @@ __wut_fsa_diropen(struct _reent *r, status = FSAOpenDir(deviceData->clientHandle, dir->fullPath, &fd); if (status < 0) { - WUT_DEBUG_REPORT("FSAOpenDir(0x%08X, %s, 0x%08X) failed: %s\n", + WUT_DEBUG_REPORT("FSAOpenDir(0x%08X, %s, %p) failed: %s\n", deviceData->clientHandle, dir->fullPath, &fd, FSAGetStatusStr(status)); r->_errno = __wut_fsa_translate_error(status); return NULL; diff --git a/libraries/wutdevoptab/devoptab_fsa_fstat.cpp b/libraries/wutdevoptab/devoptab_fsa_fstat.cpp index 0e8402c15..3550e4d69 100644 --- a/libraries/wutdevoptab/devoptab_fsa_fstat.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_fstat.cpp @@ -22,8 +22,9 @@ __wut_fsa_fstat(struct _reent *r, status = FSAGetStatFile(deviceData->clientHandle, file->fd, &fsStat); if (status < 0) { - WUT_DEBUG_REPORT("FSAGetStatFile(0x%08X, 0x%08X, 0x%08X) (%s) failed: %s\n", - deviceData->clientHandle, file->fd, &fsStat, FSAGetStatusStr(status)); + WUT_DEBUG_REPORT("FSAGetStatFile(0x%08X, 0x%08X, %p) (%s) failed: %s\n", + deviceData->clientHandle, file->fd, &fsStat, + file->fullPath, FSAGetStatusStr(status)); r->_errno = __wut_fsa_translate_error(status); return -1; } diff --git a/libraries/wutdevoptab/devoptab_fsa_open.cpp b/libraries/wutdevoptab/devoptab_fsa_open.cpp index 04850f3c6..06cd26396 100644 --- a/libraries/wutdevoptab/devoptab_fsa_open.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_open.cpp @@ -107,7 +107,7 @@ __wut_fsa_open(struct _reent *r, } fd = -1; } else { - WUT_DEBUG_REPORT("FSAOpenFileEx(0x%08X, %s, %s, 0x%X, 0x%08X, 0x%08X, 0x%08X) failed: %s\n", + WUT_DEBUG_REPORT("FSAOpenFileEx(0x%08X, %s, %s, 0x%X, 0x%08X, 0x%08X, %p) failed: %s\n", deviceData->clientHandle, file->fullPath, "w", translatedMode, openFlags, preAllocSize, &fd, FSAGetStatusStr(status)); r->_errno = __wut_fsa_translate_error(status); @@ -129,7 +129,7 @@ __wut_fsa_open(struct _reent *r, status = FSAOpenFileEx(deviceData->clientHandle, file->fullPath, fsMode, translatedMode, openFlags, preAllocSize, &fd); if (status < 0) { if (status != FS_ERROR_NOT_FOUND) { - WUT_DEBUG_REPORT("FSAOpenFileEx(0x%08X, %s, %s, 0x%X, 0x%08X, 0x%08X, 0x%08X) failed: %s\n", + WUT_DEBUG_REPORT("FSAOpenFileEx(0x%08X, %s, %s, 0x%X, 0x%08X, 0x%08X, %p) failed: %s\n", deviceData->clientHandle, file->fullPath, fsMode, translatedMode, openFlags, preAllocSize, &fd, FSAGetStatusStr(status)); } @@ -146,7 +146,7 @@ __wut_fsa_open(struct _reent *r, FSAStat stat; status = FSAGetStatFile(deviceData->clientHandle, fd, &stat); if (status < 0) { - WUT_DEBUG_REPORT("FSAGetStatFile(0x%08X, 0x%08X, 0x%08X) (%s) failed: %s\n", + WUT_DEBUG_REPORT("FSAGetStatFile(0x%08X, 0x%08X, %p) (%s) failed: %s\n", deviceData->clientHandle, fd, &stat, file->fullPath, FSAGetStatusStr(status)); r->_errno = __wut_fsa_translate_error(status); @@ -160,4 +160,4 @@ __wut_fsa_open(struct _reent *r, file->appendOffset = stat.size; } return 0; -} \ No newline at end of file +} diff --git a/libraries/wutdevoptab/devoptab_fsa_read.cpp b/libraries/wutdevoptab/devoptab_fsa_read.cpp index a52672600..315003ae7 100644 --- a/libraries/wutdevoptab/devoptab_fsa_read.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_read.cpp @@ -52,7 +52,7 @@ ssize_t __wut_fsa_read(struct _reent *r, void *fd, char *ptr, size_t len) { status = FSAReadFile(deviceData->clientHandle, tmp, 1, size, file->fd, 0); if (status < 0) { - WUT_DEBUG_REPORT("FSAReadFile(0x%08X, 0x%08X, 1, 0x%08X, 0x%08X, 0) (%s) failed: %s\n", + WUT_DEBUG_REPORT("FSAReadFile(0x%08X, %p, 1, 0x%08X, 0x%08X, 0) (%s) failed: %s\n", deviceData->clientHandle, tmp, size, file->fd, file->fullPath, FSAGetStatusStr(status)); if (bytesRead != 0) { @@ -77,4 +77,4 @@ ssize_t __wut_fsa_read(struct _reent *r, void *fd, char *ptr, size_t len) { } return bytesRead; -} \ No newline at end of file +} diff --git a/libraries/wutdevoptab/devoptab_fsa_seek.cpp b/libraries/wutdevoptab/devoptab_fsa_seek.cpp index 07ba26b53..7c0268232 100644 --- a/libraries/wutdevoptab/devoptab_fsa_seek.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_seek.cpp @@ -36,7 +36,7 @@ __wut_fsa_seek(struct _reent *r, case SEEK_END: { // Set position relative to the end of the file status = FSAGetStatFile(deviceData->clientHandle, file->fd, &fsStat); if (status < 0) { - WUT_DEBUG_REPORT("FSAGetStatFile(0x%08X, 0x%08X, 0x%08X) (%s) failed: %s\n", + WUT_DEBUG_REPORT("FSAGetStatFile(0x%08X, 0x%08X, %p) (%s) failed: %s\n", deviceData->clientHandle, file->fd, &fsStat, file->fullPath, FSAGetStatusStr(status)); r->_errno = __wut_fsa_translate_error(status); return -1; diff --git a/libraries/wutdevoptab/devoptab_fsa_stat.cpp b/libraries/wutdevoptab/devoptab_fsa_stat.cpp index 80029e777..affcbd799 100644 --- a/libraries/wutdevoptab/devoptab_fsa_stat.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_stat.cpp @@ -24,7 +24,7 @@ __wut_fsa_stat(struct _reent *r, status = FSAGetStat(deviceData->clientHandle, fixedPath, &fsStat); if (status < 0) { if (status != FS_ERROR_NOT_FOUND) { - WUT_DEBUG_REPORT("FSAGetStat(0x%08X, %s, 0x%08X) failed: %s\n", + WUT_DEBUG_REPORT("FSAGetStat(0x%08X, %s, %p) failed: %s\n", deviceData->clientHandle, fixedPath, &fsStat, FSAGetStatusStr(status)); } free(fixedPath); @@ -37,4 +37,4 @@ __wut_fsa_stat(struct _reent *r, __wut_fsa_translate_stat(deviceData->clientHandle, &fsStat, ino, st); return 0; -} \ No newline at end of file +} diff --git a/libraries/wutdevoptab/devoptab_fsa_statvfs.cpp b/libraries/wutdevoptab/devoptab_fsa_statvfs.cpp index 971d0046b..323be496b 100644 --- a/libraries/wutdevoptab/devoptab_fsa_statvfs.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_statvfs.cpp @@ -24,7 +24,7 @@ __wut_fsa_statvfs(struct _reent *r, status = FSAGetFreeSpaceSize(deviceData->clientHandle, fixedPath, &freeSpace); if (status < 0) { - WUT_DEBUG_REPORT("FSAGetFreeSpaceSize(0x%08X, %s, 0x%08X) failed: %s\n", + WUT_DEBUG_REPORT("FSAGetFreeSpaceSize(0x%08X, %s, %p) failed: %s\n", deviceData->clientHandle, fixedPath, &freeSpace, FSAGetStatusStr(status)); free(fixedPath); r->_errno = __wut_fsa_translate_error(status); @@ -52,4 +52,4 @@ __wut_fsa_statvfs(struct _reent *r, buf->f_namemax = 255; return 0; -} \ No newline at end of file +} diff --git a/libraries/wutdevoptab/devoptab_fsa_truncate.cpp b/libraries/wutdevoptab/devoptab_fsa_truncate.cpp index cd3e0503c..e16a9b825 100644 --- a/libraries/wutdevoptab/devoptab_fsa_truncate.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_truncate.cpp @@ -24,7 +24,7 @@ __wut_fsa_ftruncate(struct _reent *r, // Set the new file size status = FSASetPosFile(deviceData->clientHandle, file->fd, len); if (status < 0) { - WUT_DEBUG_REPORT("FSASetPosFile(0x%08X, 0x%08X, 0x%08X) failed: %s\n", + WUT_DEBUG_REPORT("FSASetPosFile(0x%08X, 0x%08X, 0x%08llX) failed: %s\n", deviceData->clientHandle, file->fd, len, FSAGetStatusStr(status)); r->_errno = __wut_fsa_translate_error(status); return -1; diff --git a/libraries/wutdevoptab/devoptab_fsa_write.cpp b/libraries/wutdevoptab/devoptab_fsa_write.cpp index 199b0bc7f..5a2e0d9b1 100644 --- a/libraries/wutdevoptab/devoptab_fsa_write.cpp +++ b/libraries/wutdevoptab/devoptab_fsa_write.cpp @@ -61,7 +61,7 @@ ssize_t __wut_fsa_write(struct _reent *r, void *fd, const char *ptr, size_t len) status = FSAWriteFile(deviceData->clientHandle, tmp, 1, size, file->fd, 0); if (status < 0) { - WUT_DEBUG_REPORT("FSAWriteFile(0x%08X, 0x%08X, 1, 0x%08X, 0x%08X, 0) (%s) failed: %s\n", + WUT_DEBUG_REPORT("FSAWriteFile(0x%08X, %p, 1, 0x%08X, 0x%08X, 0) (%s) failed: %s\n", deviceData->clientHandle, tmp, size, file->fd, file->fullPath, FSAGetStatusStr(status)); if (bytesWritten != 0) { return bytesWritten; // error after partial write