From de40b43037114c16633f20e112bfab30285f7d47 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Tue, 24 Jan 2023 14:53:18 +0100 Subject: [PATCH] [winpr,stream] modify logging stream length checks * Split length argument to nmemb and size for all Stream_CheckAndLogRequiredLength* functions * Add new macros to allow setting nmemb and size arguments --- winpr/include/winpr/stream.h | 35 +++++++++++++++--------- winpr/libwinpr/utils/stream.c | 51 ++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/winpr/include/winpr/stream.h b/winpr/include/winpr/stream.h index 7584bd679..13497803f 100644 --- a/winpr/include/winpr/stream.h +++ b/winpr/include/winpr/stream.h @@ -88,22 +88,31 @@ extern "C" WINPR_API wStream* Stream_StaticInit(wStream* s, BYTE* buffer, size_t size); WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer); -#define Stream_CheckAndLogRequiredLength(tag, s, len) \ - Stream_CheckAndLogRequiredLengthEx(tag, WLOG_WARN, s, len, "%s(%s:%" PRIuz ")", __FUNCTION__, \ - __FILE__, __LINE__) - WINPR_API BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s, - UINT64 len, const char* fmt, ...); - WINPR_API BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s, - UINT64 len, const char* fmt, va_list args); +#define Stream_CheckAndLogRequiredLengthOfSize(tag, s, nmemb, size) \ + Stream_CheckAndLogRequiredLengthEx(tag, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \ + __FUNCTION__, __FILE__, (size_t)__LINE__) +#define Stream_CheckAndLogRequiredLength(tag, s, len) \ + Stream_CheckAndLogRequiredLengthOfSize(tag, s, len, 1) + + WINPR_API BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s, + size_t nmemb, size_t size, const char* fmt, + ...); + WINPR_API BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s, + size_t nmemb, size_t size, const char* fmt, + va_list args); + +#define Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, nmemb, size) \ + Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \ + __FUNCTION__, __FILE__, (size_t)__LINE__) +#define Stream_CheckAndLogRequiredLengthWLog(log, s, len) \ + Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, len, 1) -#define Stream_CheckAndLogRequiredLengthWLog(log, s, len) \ - Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, len, "%s(%s:%" PRIuz ")", \ - __FUNCTION__, __FILE__, __LINE__) WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s, - UINT64 len, const char* fmt, ...); + size_t nmemb, size_t size, + const char* fmt, ...); WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s, - UINT64 len, const char* fmt, - va_list args); + size_t nmemb, size_t size, + const char* fmt, va_list args); static INLINE void Stream_Seek(wStream* s, size_t _offset) { diff --git a/winpr/libwinpr/utils/stream.c b/winpr/libwinpr/utils/stream.c index 7ee3150ca..0dcc9fe20 100644 --- a/winpr/libwinpr/utils/stream.c +++ b/winpr/libwinpr/utils/stream.c @@ -389,17 +389,18 @@ BOOL Stream_CheckAndLogRequiredCapacityWLogEx(wLog* log, DWORD level, wStream* s return TRUE; } -BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s, UINT64 len, - const char* fmt, ...) +BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s, size_t nmemb, + size_t size, const char* fmt, ...) { - const size_t actual = Stream_GetRemainingLength(s); + WINPR_ASSERT(size > 0); + const size_t actual = Stream_GetRemainingLength(s) / size; - if (actual < len) + if (actual < nmemb) { va_list args; va_start(args, fmt); - Stream_CheckAndLogRequiredLengthExVa(tag, level, s, len, fmt, args); + Stream_CheckAndLogRequiredLengthExVa(tag, level, s, nmemb, size, fmt, args); va_end(args); return FALSE; @@ -407,27 +408,30 @@ BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s return TRUE; } -BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s, UINT64 len, - const char* fmt, va_list args) +BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s, size_t nmemb, + size_t size, const char* fmt, va_list args) { - const size_t actual = Stream_GetRemainingLength(s); + WINPR_ASSERT(size > 0); + const size_t actual = Stream_GetRemainingLength(s) / size; - if (actual < len) - return Stream_CheckAndLogRequiredLengthWLogExVa(WLog_Get(tag), level, s, len, fmt, args); + if (actual < nmemb) + return Stream_CheckAndLogRequiredLengthWLogExVa(WLog_Get(tag), level, s, nmemb, size, fmt, + args); return TRUE; } -BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s, UINT64 len, - const char* fmt, ...) +BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s, size_t nmemb, + size_t size, const char* fmt, ...) { - const size_t actual = Stream_GetRemainingLength(s); + WINPR_ASSERT(size > 0); + const size_t actual = Stream_GetRemainingLength(s) / size; - if (actual < len) + if (actual < nmemb) { va_list args; va_start(args, fmt); - Stream_CheckAndLogRequiredLengthWLogExVa(log, level, s, len, fmt, args); + Stream_CheckAndLogRequiredLengthWLogExVa(log, level, s, nmemb, size, fmt, args); va_end(args); return FALSE; @@ -435,19 +439,22 @@ BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s, return TRUE; } -BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s, UINT64 len, - const char* fmt, va_list args) +BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s, size_t nmemb, + size_t size, const char* fmt, va_list args) { - const size_t actual = Stream_GetRemainingLength(s); + WINPR_ASSERT(size > 0); + const size_t actual = Stream_GetRemainingLength(s) / size; - if (actual < len) + if (actual < nmemb) { char prefix[1024] = { 0 }; vsnprintf(prefix, sizeof(prefix), fmt, args); - WLog_Print(log, level, "[%s] invalid length, got %" PRIuz ", require at least %" PRIuz, - prefix, actual, len); + WLog_Print(log, level, + "[%s] invalid length, got %" PRIuz ", require at least %" PRIuz + " [element size=%" PRIuz "]", + prefix, actual, nmemb, size); winpr_log_backtrace_ex(log, level, 20); return FALSE; } @@ -515,7 +522,7 @@ SSIZE_T Stream_Read_UTF16_String_As_UTF8_Buffer(wStream* s, size_t wcharLength, BOOL Stream_SafeSeekEx(wStream* s, size_t size, const char* file, size_t line, const char* fkt) { - if (!Stream_CheckAndLogRequiredLengthEx(STREAM_TAG, WLOG_WARN, s, size, "%s(%s:%" PRIuz ")", + if (!Stream_CheckAndLogRequiredLengthEx(STREAM_TAG, WLOG_WARN, s, size, 1, "%s(%s:%" PRIuz ")", fkt, file, line)) return FALSE;