summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/fuzzing.yml10
-rw-r--r--CMakeLists.txt14
-rw-r--r--ChangeLog16
-rw-r--r--channels/location/client/location_main.c8
-rw-r--r--channels/rail/client/rail_main.c2
-rw-r--r--channels/rail/server/rail_main.c25
-rw-r--r--channels/rdpdr/client/rdpdr_main.c16
-rw-r--r--channels/remdesk/client/remdesk_main.c2
-rw-r--r--client/SDL/dialogs/sdl_connection_dialog.hpp14
-rw-r--r--client/SDL/sdl_disp.cpp5
-rw-r--r--client/SDL/sdl_kbd.cpp65
-rw-r--r--client/SDL/sdl_kbd.hpp13
-rw-r--r--client/Wayland/wlf_cliprdr.c13
-rw-r--r--client/common/cmdline.c2
-rw-r--r--cmake/PlatformDefaults.cmake5
-rw-r--r--include/freerdp/rail.h6
-rw-r--r--libfreerdp/codec/clear.c23
-rw-r--r--libfreerdp/codec/color.c91
-rw-r--r--libfreerdp/codec/h264_ffmpeg.c1
-rw-r--r--libfreerdp/codec/interleaved.c11
-rw-r--r--libfreerdp/codec/nsc.c14
-rw-r--r--libfreerdp/codec/planar.c3
-rw-r--r--libfreerdp/codec/progressive.c144
-rw-r--r--libfreerdp/codec/rfx.c3
-rw-r--r--libfreerdp/codec/test/TestFuzzCodecs.c31
-rw-r--r--libfreerdp/codec/yuv.c3
-rw-r--r--libfreerdp/codec/zgfx.c75
-rw-r--r--libfreerdp/core/aad.c4
-rw-r--r--libfreerdp/core/gcc.c5
-rw-r--r--libfreerdp/core/info.c4
-rw-r--r--libfreerdp/core/orders.c16
-rw-r--r--libfreerdp/core/peer.c1
-rw-r--r--libfreerdp/core/redirection.c2
-rw-r--r--libfreerdp/core/test/CMakeLists.txt7
-rw-r--r--libfreerdp/core/test/TestFuzzCoreClient.c116
-rw-r--r--libfreerdp/core/test/TestFuzzCoreServer.c108
-rw-r--r--libfreerdp/core/update.c11
-rw-r--r--libfreerdp/crypto/privatekey.c4
-rw-r--r--libfreerdp/crypto/privatekey.h2
-rw-r--r--libfreerdp/emu/scard/smartcard_emulate.c4
-rw-r--r--libfreerdp/gdi/test/TestGdiCreate.c2
-rw-r--r--libfreerdp/primitives/test/TestPrimitivesYCoCg.c2
-rw-r--r--server/shadow/shadow.c2
-rw-r--r--winpr/CMakeLists.txt2
-rw-r--r--winpr/libwinpr/clipboard/synthetic.c2
-rw-r--r--winpr/libwinpr/clipboard/synthetic_file.c2
-rw-r--r--winpr/libwinpr/comm/comm.c3
-rw-r--r--winpr/libwinpr/crt/test/TestUnicodeConversion.c4
-rw-r--r--winpr/libwinpr/file/generic.c3
-rw-r--r--winpr/libwinpr/file/test/TestFileFindFirstFile.c3
-rw-r--r--winpr/libwinpr/sspi/Kerberos/kerberos.c14
-rw-r--r--winpr/libwinpr/timezone/timezone.c40
-rw-r--r--winpr/libwinpr/utils/debug.c2
-rw-r--r--winpr/libwinpr/utils/image.c60
-rw-r--r--winpr/libwinpr/utils/test/TestStream.c6
55 files changed, 734 insertions, 312 deletions
diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml
index 948fd42..cf4794f 100644
--- a/.github/workflows/fuzzing.yml
+++ b/.github/workflows/fuzzing.yml
@@ -3,8 +3,10 @@ name: Fuzzing testing
on:
workflow_dispatch:
branches: [ master, stable* ]
- pull_request_target:
+ pull_request:
branches: [ master, stable* ]
+ schedule:
+ - cron: "0 3 21 * *"
jobs:
fuzzing:
@@ -15,14 +17,10 @@ jobs:
strategy:
fail-fast: false
matrix:
- sanitizer: [address]
+ sanitizer: [address, undefined]
steps:
- - uses: suzuki-shunsuke/get-pr-action@v0.1.0
- id: pr
- uses: actions/checkout@v4
- with:
- ref: ${{steps.pr.outputs.merge_commit_sha}}
- name: Build fuzzers (${{ matrix.sanitizer }})
id: build
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7700e18..9ee67f8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -91,7 +91,7 @@ if ($ENV{BUILD_NUMBER})
endif()
set(VERSION_REGEX "^(.*)([0-9]+)\\.([0-9]+)\\.([0-9]+)-?(.*)")
-set(RAW_VERSION_STRING "3.5.0")
+set(RAW_VERSION_STRING "3.5.1")
if(EXISTS "${PROJECT_SOURCE_DIR}/.source_tag")
file(READ ${PROJECT_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
elseif(USE_VERSION_FROM_GIT_TAG)
@@ -202,11 +202,6 @@ if (EXPORT_ALL_SYMBOLS)
add_definitions(-DEXPORT_ALL_SYMBOLS)
endif(EXPORT_ALL_SYMBOLS)
-if(FREEBSD)
- find_path(EPOLLSHIM_INCLUDE_DIR NAMES sys/epoll.h sys/timerfd.h HINTS /usr/local/include/libepoll-shim)
- find_library(EPOLLSHIM_LIBS NAMES epoll-shim libepoll-shim HINTS /usr/local/lib)
-endif()
-
# Compiler-specific flags
if(CMAKE_COMPILER_IS_GNUCC)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "i686")
@@ -499,10 +494,6 @@ set(FFMPEG_FEATURE_TYPE "RECOMMENDED")
set(FFMPEG_FEATURE_PURPOSE "multimedia")
set(FFMPEG_FEATURE_DESCRIPTION "multimedia redirection, audio and video playback")
-set(VAAPI_FEATURE_TYPE "OPTIONAL")
-set(VAAPI_FEATURE_PURPOSE "multimedia")
-set(VAAPI_FEATURE_DESCRIPTION "VA-API hardware acceleration for video playback")
-
set(OPENH264_FEATURE_TYPE "OPTIONAL")
set(OPENH264_FEATURE_PURPOSE "codec")
set(OPENH264_FEATURE_DESCRIPTION "use OpenH264 library")
@@ -535,12 +526,10 @@ if(WIN32)
set(WAYLAND_FEATURE_TYPE "DISABLED")
set(PCSC_FEATURE_TYPE "DISABLED")
set(FFMPEG_FEATURE_TYPE "OPTIONAL")
- set(VAAPI_FEATURE_TYPE "DISABLED")
endif()
if(APPLE)
set(FFMPEG_FEATURE_TYPE "OPTIONAL")
- set(VAAPI_FEATURE_TYPE "DISABLED")
set(WAYLAND_FEATURE_TYPE "DISABLED")
if(IOS)
set(PCSC_FEATURE_TYPE "DISABLED")
@@ -550,7 +539,6 @@ endif()
if(ANDROID)
set(WAYLAND_FEATURE_TYPE "DISABLED")
set(PCSC_FEATURE_TYPE "DISABLED")
- set(VAAPI_FEATURE_TYPE "DISABLED")
endif()
find_feature(Wayland ${WAYLAND_FEATURE_TYPE} ${WAYLAND_FEATURE_PURPOSE} ${WAYLAND_FEATURE_DESCRIPTION})
diff --git a/ChangeLog b/ChangeLog
index ccba111..013bbd8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+# 2024-04-22 Version 3.5.1
+
+This release eliminates a bunch of issues detected during oss-fuzz runs.
+The test coverage was increased and detected issues eliminates, so an update
+is highly recommended.
+
+Noteworthy changes:
+* Lots of fixes for oss-fuzz reports
+* Timezone detection fixes (#10106)
+* SDL key remapping support (#10103)
+* Improved help (#10099)
+* FreeBSD epoll detection fix (#10097)
+
+For a complete and detailed change log since the last release run:
+git log 3.5.1...3.5.0
+
# 2024-04-16 Version 3.5.0
This release focus is on squashing bugs.
diff --git a/channels/location/client/location_main.c b/channels/location/client/location_main.c
index 281070f..df6b82e 100644
--- a/channels/location/client/location_main.c
+++ b/channels/location/client/location_main.c
@@ -110,7 +110,7 @@ static UINT location_channel_send(IWTSVirtualChannel* channel, wStream* s)
static UINT location_send_client_ready_pdu(const LOCATION_CALLBACK* callback)
{
wStream sbuffer = { 0 };
- char buffer[32] = { 0 };
+ BYTE buffer[32] = { 0 };
wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer));
WINPR_ASSERT(s);
@@ -210,7 +210,7 @@ static UINT location_send_base_location3d(IWTSVirtualChannel* channel,
const RDPLOCATION_BASE_LOCATION3D_PDU* pdu)
{
wStream sbuffer = { 0 };
- char buffer[32] = { 0 };
+ BYTE buffer[32] = { 0 };
wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer));
WINPR_ASSERT(s);
WINPR_ASSERT(channel);
@@ -251,7 +251,7 @@ static UINT location_send_location2d_delta(IWTSVirtualChannel* channel,
const RDPLOCATION_LOCATION2D_DELTA_PDU* pdu)
{
wStream sbuffer = { 0 };
- char buffer[32] = { 0 };
+ BYTE buffer[32] = { 0 };
wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer));
WINPR_ASSERT(s);
@@ -287,7 +287,7 @@ static UINT location_send_location3d_delta(IWTSVirtualChannel* channel,
const RDPLOCATION_LOCATION3D_DELTA_PDU* pdu)
{
wStream sbuffer = { 0 };
- char buffer[32] = { 0 };
+ BYTE buffer[32] = { 0 };
wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer));
WINPR_ASSERT(s);
diff --git a/channels/rail/client/rail_main.c b/channels/rail/client/rail_main.c
index c5828c1..3878807 100644
--- a/channels/rail/client/rail_main.c
+++ b/channels/rail/client/rail_main.c
@@ -112,7 +112,7 @@ UINT rail_send_channel_data(railPlugin* rail, wStream* src)
*/
static UINT rail_client_execute(RailClientContext* context, const RAIL_EXEC_ORDER* exec)
{
- char* exeOrFile = NULL;
+ const char* exeOrFile = NULL;
UINT error = 0;
railPlugin* rail = NULL;
UINT16 flags = 0;
diff --git a/channels/rail/server/rail_main.c b/channels/rail/server/rail_main.c
index 8e38c2b..5089646 100644
--- a/channels/rail/server/rail_main.c
+++ b/channels/rail/server/rail_main.c
@@ -650,7 +650,7 @@ static UINT rail_read_client_status_order(wStream* s, RAIL_CLIENT_STATUS_ORDER*
*
* @return 0 on success, otherwise a Win32 error code
*/
-static UINT rail_read_exec_order(wStream* s, RAIL_EXEC_ORDER* exec)
+static UINT rail_read_exec_order(wStream* s, RAIL_EXEC_ORDER* exec, char* args[])
{
RAIL_EXEC_ORDER order = { 0 };
UINT16 exeLen = 0;
@@ -671,30 +671,31 @@ static UINT rail_read_exec_order(wStream* s, RAIL_EXEC_ORDER* exec)
if (exeLen > 0)
{
const SSIZE_T len = exeLen / sizeof(WCHAR);
- exec->RemoteApplicationProgram = Stream_Read_UTF16_String_As_UTF8(s, len, NULL);
+ exec->RemoteApplicationProgram = args[0] = Stream_Read_UTF16_String_As_UTF8(s, len, NULL);
if (!exec->RemoteApplicationProgram)
goto fail;
}
if (workLen > 0)
{
const SSIZE_T len = workLen / sizeof(WCHAR);
- exec->RemoteApplicationWorkingDir = Stream_Read_UTF16_String_As_UTF8(s, len, NULL);
+ exec->RemoteApplicationWorkingDir = args[1] =
+ Stream_Read_UTF16_String_As_UTF8(s, len, NULL);
if (!exec->RemoteApplicationWorkingDir)
goto fail;
}
if (argLen > 0)
{
const SSIZE_T len = argLen / sizeof(WCHAR);
- exec->RemoteApplicationArguments = Stream_Read_UTF16_String_As_UTF8(s, len, NULL);
+ exec->RemoteApplicationArguments = args[2] = Stream_Read_UTF16_String_As_UTF8(s, len, NULL);
if (!exec->RemoteApplicationArguments)
goto fail;
}
return CHANNEL_RC_OK;
fail:
- free(exec->RemoteApplicationProgram);
- free(exec->RemoteApplicationArguments);
- free(exec->RemoteApplicationWorkingDir);
+ free(args[0]);
+ free(args[1]);
+ free(args[2]);
*exec = order;
return ERROR_INTERNAL_ERROR;
}
@@ -948,12 +949,14 @@ static UINT rail_recv_client_client_status_order(RailServerContext* context,
static UINT rail_recv_client_exec_order(RailServerContext* context, wStream* s)
{
UINT error = 0;
+ char* args[3] = { 0 };
RAIL_EXEC_ORDER exec = { 0 };
if (!context || !s)
return ERROR_INVALID_PARAMETER;
- if ((error = rail_read_exec_order(s, &exec)))
+ error = rail_read_exec_order(s, &exec, args);
+ if (error)
{
WLog_ERR(TAG, "rail_read_client_status_order failed with error %" PRIu32 "!", error);
return error;
@@ -964,9 +967,9 @@ static UINT rail_recv_client_exec_order(RailServerContext* context, wStream* s)
if (error)
WLog_ERR(TAG, "context.Exec failed with error %" PRIu32 "", error);
- free(exec.RemoteApplicationProgram);
- free(exec.RemoteApplicationArguments);
- free(exec.RemoteApplicationWorkingDir);
+ free(args[0]);
+ free(args[1]);
+ free(args[2]);
return error;
}
diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c
index 2ffa951..8cbb359 100644
--- a/channels/rdpdr/client/rdpdr_main.c
+++ b/channels/rdpdr/client/rdpdr_main.c
@@ -1861,7 +1861,7 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
UINT status = 0;
rdpdrPlugin* plugin = (rdpdrPlugin*)rdpdr;
- if (!rdpdr || !s)
+ if (!s)
{
Stream_Release(s);
return CHANNEL_RC_NULL_DATA;
@@ -1870,16 +1870,14 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
if (!plugin)
{
Stream_Release(s);
- status = CHANNEL_RC_BAD_INIT_HANDLE;
- }
- else
- {
- const size_t pos = Stream_GetPosition(s);
- rdpdr_dump_send_packet(rdpdr->log, WLOG_TRACE, s, "[rdpdr-channel] send");
- status = plugin->channelEntryPoints.pVirtualChannelWriteEx(
- plugin->InitHandle, plugin->OpenHandle, Stream_Buffer(s), pos, s);
+ return CHANNEL_RC_BAD_INIT_HANDLE;
}
+ const size_t pos = Stream_GetPosition(s);
+ rdpdr_dump_send_packet(rdpdr->log, WLOG_TRACE, s, "[rdpdr-channel] send");
+ status = plugin->channelEntryPoints.pVirtualChannelWriteEx(
+ plugin->InitHandle, plugin->OpenHandle, Stream_Buffer(s), pos, s);
+
if (status != CHANNEL_RC_OK)
{
Stream_Release(s);
diff --git a/channels/remdesk/client/remdesk_main.c b/channels/remdesk/client/remdesk_main.c
index 1d39ed1..269e9a8 100644
--- a/channels/remdesk/client/remdesk_main.c
+++ b/channels/remdesk/client/remdesk_main.c
@@ -69,7 +69,7 @@ static UINT remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s)
*/
static UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk)
{
- char* name = NULL;
+ const char* name = NULL;
char* pass = NULL;
const char* password = NULL;
rdpSettings* settings = NULL;
diff --git a/client/SDL/dialogs/sdl_connection_dialog.hpp b/client/SDL/dialogs/sdl_connection_dialog.hpp
index f21f538..57e5596 100644
--- a/client/SDL/dialogs/sdl_connection_dialog.hpp
+++ b/client/SDL/dialogs/sdl_connection_dialog.hpp
@@ -89,15 +89,15 @@ class SDLConnectionDialog
private:
struct widget_cfg_t
{
- SDL_Color fgcolor;
- SDL_Color bgcolor;
+ SDL_Color fgcolor = {};
+ SDL_Color bgcolor = {};
SdlWidget widget;
};
private:
- rdpContext* _context;
- SDL_Window* _window;
- SDL_Renderer* _renderer;
+ rdpContext* _context = nullptr;
+ SDL_Window* _window = nullptr;
+ SDL_Renderer* _renderer = nullptr;
mutable std::mutex _mux;
std::string _title;
std::string _msg;
@@ -124,6 +124,6 @@ class SDLConnectionDialogHider
SDLConnectionDialog* get(rdpContext* context);
private:
- SDLConnectionDialog* _dialog;
- bool _visible;
+ SDLConnectionDialog* _dialog = nullptr;
+ bool _visible = false;
};
diff --git a/client/SDL/sdl_disp.cpp b/client/SDL/sdl_disp.cpp
index ffd13c8..34863ba 100644
--- a/client/SDL/sdl_disp.cpp
+++ b/client/SDL/sdl_disp.cpp
@@ -142,6 +142,8 @@ static BOOL sdl_disp_check_context(void* context, SdlContext** ppsdl, sdlDispCon
return FALSE;
auto sdl = get_context(context);
+ if (!sdl)
+ return FALSE;
if (!sdl->context()->settings)
return FALSE;
@@ -200,6 +202,9 @@ Uint32 sdlDispContext::OnTimer(Uint32 interval, void* param)
return 0;
SdlContext* sdl = ctx->_sdl;
+ if (!sdl)
+ return 0;
+
sdlDispContext* sdlDisp = nullptr;
rdpSettings* settings = nullptr;
diff --git a/client/SDL/sdl_kbd.cpp b/client/SDL/sdl_kbd.cpp
index 984614e..c6e668d 100644
--- a/client/SDL/sdl_kbd.cpp
+++ b/client/SDL/sdl_kbd.cpp
@@ -488,6 +488,66 @@ uint32_t sdlInput::prefKeyValue(const std::string& key, uint32_t fallback)
return val;
}
+std::list<std::string> sdlInput::tokenize(const std::string& data, const std::string& delimiter)
+{
+ size_t lastpos = 0;
+ size_t pos = 0;
+ std::list<std::string> list;
+ while ((pos = data.find(delimiter, lastpos)) != std::string::npos)
+ {
+ auto token = data.substr(lastpos, pos);
+ lastpos = pos + 1;
+ list.push_back(token);
+ }
+ auto token = data.substr(lastpos);
+ list.push_back(token);
+ return list;
+}
+
+bool sdlInput::extract(const std::string& token, uint32_t& key, uint32_t& value)
+{
+ int rc = sscanf(token.c_str(), "%" PRIu32 "=%" PRIu32, &key, &value);
+ if (rc != 2)
+ rc = sscanf(token.c_str(), "%" PRIx32 "=%" PRIx32 "", &key, &value);
+ if (rc != 2)
+ rc = sscanf(token.c_str(), "%" PRIu32 "=%" PRIx32, &key, &value);
+ if (rc != 2)
+ rc = sscanf(token.c_str(), "%" PRIx32 "=%" PRIu32, &key, &value);
+ return (rc == 2);
+}
+
+uint32_t sdlInput::remapScancode(uint32_t scancode)
+{
+ if (!_remapInitialized.exchange(true))
+ remapInitialize();
+ auto it = _remapList.find(scancode);
+ if (it != _remapList.end())
+ return it->second;
+ return scancode;
+}
+
+void sdlInput::remapInitialize()
+{
+ WINPR_ASSERT(_sdl);
+
+ auto context = _sdl->context();
+ WINPR_ASSERT(context);
+ auto KeyboardRemappingList =
+ freerdp_settings_get_string(context->settings, FreeRDP_KeyboardRemappingList);
+ if (!KeyboardRemappingList)
+ return;
+
+ auto list = tokenize(KeyboardRemappingList);
+ for (auto& token : list)
+ {
+ uint32_t key = 0;
+ uint32_t value = 0;
+ if (!extract(token, key, value))
+ continue;
+ _remapList.emplace(key, value);
+ }
+}
+
BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
{
WINPR_ASSERT(ev);
@@ -526,8 +586,10 @@ BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
}
}
}
+
+ auto scancode = remapScancode(rdp_scancode);
return freerdp_input_send_keyboard_event_ex(_sdl->context()->input, ev->type == SDL_KEYDOWN,
- ev->repeat, rdp_scancode);
+ ev->repeat, scancode);
}
BOOL sdlInput::keyboard_grab(Uint32 windowID, SDL_bool enable)
@@ -564,5 +626,4 @@ BOOL sdlInput::mouse_grab(Uint32 windowID, SDL_bool enable)
sdlInput::sdlInput(SdlContext* sdl) : _sdl(sdl), _lastWindowID(UINT32_MAX)
{
- WINPR_ASSERT(_sdl);
}
diff --git a/client/SDL/sdl_kbd.hpp b/client/SDL/sdl_kbd.hpp
index 2a6c7fa..c75da4d 100644
--- a/client/SDL/sdl_kbd.hpp
+++ b/client/SDL/sdl_kbd.hpp
@@ -20,6 +20,9 @@
#pragma once
#include <string>
+#include <map>
+#include <list>
+#include <atomic>
#include <winpr/wtypes.h>
#include <freerdp/freerdp.h>
@@ -51,6 +54,16 @@ class sdlInput
static uint32_t prefKeyValue(const std::string& key, uint32_t fallback = SDL_SCANCODE_UNKNOWN);
private:
+ static std::list<std::string> tokenize(const std::string& data,
+ const std::string& delimiter = ",");
+ static bool extract(const std::string& token, uint32_t& key, uint32_t& value);
+
+ uint32_t remapScancode(uint32_t scancode);
+ void remapInitialize();
+
+ private:
SdlContext* _sdl;
Uint32 _lastWindowID;
+ std::map<uint32_t, uint32_t> _remapList;
+ std::atomic<bool> _remapInitialized = false;
};
diff --git a/client/Wayland/wlf_cliprdr.c b/client/Wayland/wlf_cliprdr.c
index f0c3318..112ffd1 100644
--- a/client/Wayland/wlf_cliprdr.c
+++ b/client/Wayland/wlf_cliprdr.c
@@ -70,6 +70,13 @@ typedef struct
char* responseMime;
} wlf_request;
+typedef struct
+{
+ const FILE* responseFile;
+ UINT32 responseFormat;
+ const char* responseMime;
+} wlf_const_request;
+
struct wlf_clipboard
{
wlfContext* wfc;
@@ -311,7 +318,7 @@ static BOOL wlf_cliprdr_add_client_format(wfClipboard* clipboard, const char* mi
*
* @return 0 on success, otherwise a Win32 error code
*/
-static UINT wlf_cliprdr_send_data_request(wfClipboard* clipboard, const wlf_request* rq)
+static UINT wlf_cliprdr_send_data_request(wfClipboard* clipboard, const wlf_const_request* rq)
{
WINPR_ASSERT(rq);
@@ -522,7 +529,7 @@ static void wlf_cliprdr_transfer_data(UwacSeat* seat, void* context, const char*
EnterCriticalSection(&clipboard->lock);
- wlf_request request = { 0 };
+ wlf_const_request request = { 0 };
if (wlf_mime_is_html(mime))
{
request.responseMime = mime_html;
@@ -720,7 +727,7 @@ wlf_cliprdr_server_format_data_request(CliprdrClientContext* context,
const CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
{
UINT rc = CHANNEL_RC_OK;
- BYTE* data = NULL;
+ char* data = NULL;
size_t size = 0;
const char* mime = NULL;
UINT32 formatId = 0;
diff --git a/client/common/cmdline.c b/client/common/cmdline.c
index 01d5b37..8d24af7 100644
--- a/client/common/cmdline.c
+++ b/client/common/cmdline.c
@@ -5321,7 +5321,7 @@ static void argv_free(int* pargc, char** pargv[])
free(argv);
}
-static BOOL argv_append(int* pargc, char** pargv[], const char* what)
+static BOOL argv_append(int* pargc, char** pargv[], char* what)
{
WINPR_ASSERT(pargc);
WINPR_ASSERT(pargv);
diff --git a/cmake/PlatformDefaults.cmake b/cmake/PlatformDefaults.cmake
index 30c8a92..0037ebe 100644
--- a/cmake/PlatformDefaults.cmake
+++ b/cmake/PlatformDefaults.cmake
@@ -100,4 +100,9 @@ if (USE_PLATFORM_DEFAULT)
set(WINPR_TIMEZONE_FILE "/var/db/zoneinfo")
endif()
add_definitions("-DWINPR_TIMEZONE_FILE=\"${WINPR_TIMEZONE_FILE}\"")
+
+ if(FREEBSD)
+ find_path(EPOLLSHIM_INCLUDE_DIR NAMES sys/epoll.h sys/timerfd.h HINTS /usr/local/include/libepoll-shim)
+ find_library(EPOLLSHIM_LIBS NAMES epoll-shim libepoll-shim HINTS /usr/local/lib)
+ endif()
endif()
diff --git a/include/freerdp/rail.h b/include/freerdp/rail.h
index b3cd702..64a01e5 100644
--- a/include/freerdp/rail.h
+++ b/include/freerdp/rail.h
@@ -347,9 +347,9 @@ typedef struct
typedef struct
{
UINT16 flags;
- char* RemoteApplicationProgram;
- char* RemoteApplicationWorkingDir;
- char* RemoteApplicationArguments;
+ const char* RemoteApplicationProgram;
+ const char* RemoteApplicationWorkingDir;
+ const char* RemoteApplicationArguments;
} RAIL_EXEC_ORDER;
typedef struct
diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c
index 512aeae..c9538c8 100644
--- a/libfreerdp/codec/clear.c
+++ b/libfreerdp/codec/clear.c
@@ -500,12 +500,12 @@ static BOOL clear_decompress_subcodecs_data(CLEAR_CONTEXT* clear, wStream* s,
{
case 0: /* Uncompressed */
{
- UINT32 nSrcStep = width * FreeRDPGetBytesPerPixel(PIXEL_FORMAT_BGR24);
- UINT32 nSrcSize = nSrcStep * height;
+ const UINT32 nSrcStep = width * FreeRDPGetBytesPerPixel(PIXEL_FORMAT_BGR24);
+ const size_t nSrcSize = 1ull * nSrcStep * height;
if (bitmapDataByteCount != nSrcSize)
{
- WLog_ERR(TAG, "bitmapDataByteCount %" PRIu32 " != nSrcSize %" PRIu32 "",
+ WLog_ERR(TAG, "bitmapDataByteCount %" PRIu32 " != nSrcSize %" PRIuz "",
bitmapDataByteCount, nSrcSize);
return FALSE;
}
@@ -798,10 +798,16 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
count = (vBarPixelCount > y) ? (vBarPixelCount - y) : 0;
if (count > 0)
- pSrcPixel =
- &vBarShortEntry
- ->pixels[(y - vBarYOn) * FreeRDPGetBytesPerPixel(clear->format)];
-
+ {
+ const size_t offset =
+ (1ull * y - vBarYOn) * FreeRDPGetBytesPerPixel(clear->format);
+ pSrcPixel = &vBarShortEntry->pixels[offset];
+ if (offset + count > vBarShortEntry->count)
+ {
+ WLog_ERR(TAG, "offset + count > vBarShortEntry->count");
+ return FALSE;
+ }
+ }
for (UINT32 x = 0; x < count; x++)
{
UINT32 color = 0;
@@ -1169,7 +1175,10 @@ CLEAR_CONTEXT* clear_context_new(BOOL Compressor)
return clear;
error_nsc:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
clear_context_free(clear);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c
index 186d477..2c3d08a 100644
--- a/libfreerdp/codec/color.c
+++ b/libfreerdp/codec/color.c
@@ -583,16 +583,16 @@ static BOOL freerdp_image_copy_no_overlap(BYTE* WINPR_RESTRICT pDstData, DWORD D
UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
const gdiPalette* WINPR_RESTRICT palette, UINT32 flags)
{
- const UINT32 dstByte = FreeRDPGetBytesPerPixel(DstFormat);
- const UINT32 srcByte = FreeRDPGetBytesPerPixel(SrcFormat);
- const UINT32 copyDstWidth = nWidth * dstByte;
- const UINT32 xSrcOffset = nXSrc * srcByte;
- const UINT32 xDstOffset = nXDst * dstByte;
+ const SSIZE_T dstByte = FreeRDPGetBytesPerPixel(DstFormat);
+ const SSIZE_T srcByte = FreeRDPGetBytesPerPixel(SrcFormat);
+ const SSIZE_T copyDstWidth = nWidth * dstByte;
+ const SSIZE_T xSrcOffset = nXSrc * srcByte;
+ const SSIZE_T xDstOffset = nXDst * dstByte;
const BOOL vSrcVFlip = (flags & FREERDP_FLIP_VERTICAL) ? TRUE : FALSE;
- UINT32 srcVOffset = 0;
- INT32 srcVMultiplier = 1;
- UINT32 dstVOffset = 0;
- INT32 dstVMultiplier = 1;
+ SSIZE_T srcVOffset = 0;
+ SSIZE_T srcVMultiplier = 1;
+ SSIZE_T dstVOffset = 0;
+ SSIZE_T dstVMultiplier = 1;
if ((nHeight > INT32_MAX) || (nWidth > INT32_MAX))
return FALSE;
@@ -608,24 +608,24 @@ static BOOL freerdp_image_copy_no_overlap(BYTE* WINPR_RESTRICT pDstData, DWORD D
if (vSrcVFlip)
{
- srcVOffset = (nHeight - 1) * nSrcStep;
+ srcVOffset = (nHeight - 1ll) * nSrcStep;
srcVMultiplier = -1;
}
if (((flags & FREERDP_KEEP_DST_ALPHA) != 0) && FreeRDPColorHasAlpha(DstFormat))
{
- for (UINT32 y = 0; y < nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
const BYTE* WINPR_RESTRICT srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
BYTE* WINPR_RESTRICT dstLine =
- &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
UINT32 color = FreeRDPReadColor(&srcLine[nXSrc * srcByte], SrcFormat);
UINT32 oldColor = color;
UINT32 dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
FreeRDPWriteColorIgnoreAlpha(&dstLine[nXDst * dstByte], DstFormat, dstColor);
- for (UINT32 x = 1; x < nWidth; x++)
+ for (SSIZE_T x = 1; x < nWidth; x++)
{
color = FreeRDPReadColor(&srcLine[(x + nXSrc) * srcByte], SrcFormat);
if (color == oldColor)
@@ -645,29 +645,29 @@ static BOOL freerdp_image_copy_no_overlap(BYTE* WINPR_RESTRICT pDstData, DWORD D
}
else if (FreeRDPAreColorFormatsEqualNoAlpha(SrcFormat, DstFormat))
{
- for (UINT32 y = 0; y < nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
const BYTE* WINPR_RESTRICT srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
BYTE* WINPR_RESTRICT dstLine =
- &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
memcpy(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
}
}
else
{
- for (UINT32 y = 0; y < nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
const BYTE* WINPR_RESTRICT srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
BYTE* WINPR_RESTRICT dstLine =
- &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
UINT32 color = FreeRDPReadColor(&srcLine[nXSrc * srcByte], SrcFormat);
UINT32 oldColor = color;
UINT32 dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
FreeRDPWriteColor(&dstLine[nXDst * dstByte], DstFormat, dstColor);
- for (UINT32 x = 1; x < nWidth; x++)
+ for (SSIZE_T x = 1; x < nWidth; x++)
{
color = FreeRDPReadColor(&srcLine[(x + nXSrc) * srcByte], SrcFormat);
if (color == oldColor)
@@ -699,10 +699,10 @@ static BOOL freerdp_image_copy_overlap(BYTE* pDstData, DWORD DstFormat, UINT32 n
const UINT32 xSrcOffset = nXSrc * srcByte;
const UINT32 xDstOffset = nXDst * dstByte;
const BOOL vSrcVFlip = (flags & FREERDP_FLIP_VERTICAL) ? TRUE : FALSE;
- UINT32 srcVOffset = 0;
- INT32 srcVMultiplier = 1;
- UINT32 dstVOffset = 0;
- INT32 dstVMultiplier = 1;
+ SSIZE_T srcVOffset = 0;
+ SSIZE_T srcVMultiplier = 1;
+ SSIZE_T dstVOffset = 0;
+ SSIZE_T dstVMultiplier = 1;
if ((nHeight > INT32_MAX) || (nWidth > INT32_MAX))
return FALSE;
@@ -718,16 +718,16 @@ static BOOL freerdp_image_copy_overlap(BYTE* pDstData, DWORD DstFormat, UINT32 n
if (vSrcVFlip)
{
- srcVOffset = (nHeight - 1) * nSrcStep;
+ srcVOffset = (nHeight - 1ll) * nSrcStep;
srcVMultiplier = -1;
}
if (((flags & FREERDP_KEEP_DST_ALPHA) != 0) && FreeRDPColorHasAlpha(DstFormat))
{
- for (UINT32 y = 0; y < nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
- const BYTE* srcLine = &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ const BYTE* srcLine = &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
UINT32 color = FreeRDPReadColor(&srcLine[nXSrc * srcByte], SrcFormat);
UINT32 oldColor = color;
@@ -756,44 +756,44 @@ static BOOL freerdp_image_copy_overlap(BYTE* pDstData, DWORD DstFormat, UINT32 n
/* Copy down */
if (nYDst < nYSrc)
{
- for (INT32 y = 0; y < (INT32)nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
const BYTE* srcLine =
&pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
memcpy(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
}
}
/* Copy up */
else if (nYDst > nYSrc)
{
- for (INT32 y = (INT32)nHeight - 1; y >= 0; y--)
+ for (SSIZE_T y = nHeight - 1; y >= 0; y--)
{
const BYTE* srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
memcpy(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
}
}
/* Copy left */
else if (nXSrc > nXDst)
{
- for (INT32 y = 0; y < (INT32)nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
const BYTE* srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
memmove(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
}
}
/* Copy right */
else if (nXSrc < nXDst)
{
- for (INT32 y = (INT32)nHeight - 1; y >= 0; y--)
+ for (SSIZE_T y = nHeight - 1; y >= 0; y--)
{
const BYTE* srcLine =
- &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
memmove(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
}
}
@@ -804,16 +804,16 @@ static BOOL freerdp_image_copy_overlap(BYTE* pDstData, DWORD DstFormat, UINT32 n
}
else
{
- for (UINT32 y = 0; y < nHeight; y++)
+ for (SSIZE_T y = 0; y < nHeight; y++)
{
- const BYTE* srcLine = &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
- BYTE* dstLine = &pDstData[(y + nYDst) * nDstStep * dstVMultiplier + dstVOffset];
+ const BYTE* srcLine = &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
+ BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
UINT32 color = FreeRDPReadColor(&srcLine[nXSrc * srcByte], SrcFormat);
UINT32 oldColor = color;
UINT32 dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
FreeRDPWriteColor(&dstLine[nXDst * dstByte], DstFormat, dstColor);
- for (UINT32 x = 1; x < nWidth; x++)
+ for (SSIZE_T x = 1; x < nWidth; x++)
{
color = FreeRDPReadColor(&srcLine[(x + nXSrc) * srcByte], SrcFormat);
if (color == oldColor)
@@ -847,6 +847,9 @@ BOOL freerdp_image_copy(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32
if (!pDstData || !pSrcData)
return FALSE;
+ if ((nWidth == 0) || (nHeight == 0))
+ return TRUE;
+
if (nDstStep == 0)
nDstStep = nWidth * FreeRDPGetBytesPerPixel(DstFormat);
diff --git a/libfreerdp/codec/h264_ffmpeg.c b/libfreerdp/codec/h264_ffmpeg.c
index 54492e1..a2ad12f 100644
--- a/libfreerdp/codec/h264_ffmpeg.c
+++ b/libfreerdp/codec/h264_ffmpeg.c
@@ -636,6 +636,7 @@ static BOOL libavcodec_init(H264_CONTEXT* h264)
goto fail_hwdevice_create;
}
}
+ WLog_Print(h264->log, WLOG_INFO, "Using VAAPI for accelerated H264 decoding");
sys->codecDecoderContext->get_format = libavcodec_get_format;
sys->hw_pix_fmt = AV_PIX_FMT_VAAPI;
diff --git a/libfreerdp/codec/interleaved.c b/libfreerdp/codec/interleaved.c
index df148b6..262895d 100644
--- a/libfreerdp/codec/interleaved.c
+++ b/libfreerdp/codec/interleaved.c
@@ -212,7 +212,7 @@ static UINT ExtractRunLengthRegularFgBg(const BYTE* pbOrderHdr, const BYTE* pbEn
runLength = (*pbOrderHdr) & g_MaskRegularRunLength;
if (runLength == 0)
{
- if (!buffer_within_range(pbOrderHdr, 1, pbEnd))
+ if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
{
*advance = 0;
return 0;
@@ -262,7 +262,7 @@ static UINT ExtractRunLengthRegular(const BYTE* pbOrderHdr, const BYTE* pbEnd, U
runLength = *pbOrderHdr & g_MaskRegularRunLength;
if (runLength == 0)
{
- if (!buffer_within_range(pbOrderHdr, 1, pbEnd))
+ if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
{
*advance = 0;
return 0;
@@ -282,7 +282,7 @@ static UINT ExtractRunLengthMegaMega(const BYTE* pbOrderHdr, const BYTE* pbEnd,
WINPR_ASSERT(pbEnd);
WINPR_ASSERT(advance);
- if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
+ if (!buffer_within_range(pbOrderHdr, 3, pbEnd))
{
*advance = 0;
return 0;
@@ -305,7 +305,7 @@ static UINT ExtractRunLengthLite(const BYTE* pbOrderHdr, const BYTE* pbEnd, UINT
runLength = *pbOrderHdr & g_MaskLiteRunLength;
if (runLength == 0)
{
- if (!buffer_within_range(pbOrderHdr, 1, pbEnd))
+ if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
{
*advance = 0;
return 0;
@@ -735,7 +735,10 @@ BITMAP_INTERLEAVED_CONTEXT* bitmap_interleaved_context_new(BOOL Compressor)
return interleaved;
fail:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
bitmap_interleaved_context_free(interleaved);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/nsc.c b/libfreerdp/codec/nsc.c
index 74f4e28..d1b594b 100644
--- a/libfreerdp/codec/nsc.c
+++ b/libfreerdp/codec/nsc.c
@@ -86,8 +86,8 @@ static BOOL nsc_decode(NSC_CONTEXT* context)
for (UINT32 x = 0; x < context->width; x++)
{
INT16 y_val = (INT16)*yplane;
- INT16 co_val = (INT16)(INT8)(*coplane << shift);
- INT16 cg_val = (INT16)(INT8)(*cgplane << shift);
+ INT16 co_val = (INT16)(INT8)(((INT16)*coplane) << shift);
+ INT16 cg_val = (INT16)(INT8)(((INT16)*cgplane) << shift);
INT16 r_val = y_val + co_val - cg_val;
INT16 g_val = y_val + cg_val;
INT16 b_val = y_val - co_val - cg_val;
@@ -250,6 +250,13 @@ static BOOL nsc_stream_initialize(NSC_CONTEXT* context, wStream* s)
}
Stream_Read_UINT8(s, context->ColorLossLevel); /* ColorLossLevel (1 byte) */
+ if ((context->ColorLossLevel < 1) || (context->ColorLossLevel > 7))
+ {
+ WLog_Print(context->priv->log, WLOG_ERROR,
+ "ColorLossLevel=%" PRIu8 " out of range, must be [1,7] inclusive",
+ context->ColorLossLevel);
+ return FALSE;
+ }
Stream_Read_UINT8(s, context->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
Stream_Seek(s, 2); /* Reserved (2 bytes) */
context->Planes = Stream_Pointer(s);
@@ -363,7 +370,10 @@ NSC_CONTEXT* nsc_context_new(void)
NSC_INIT_SIMD(context);
return context;
error:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
nsc_context_free(context);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c
index 4b51a02..e894761 100644
--- a/libfreerdp/codec/planar.c
+++ b/libfreerdp/codec/planar.c
@@ -1747,7 +1747,10 @@ BITMAP_PLANAR_CONTEXT* freerdp_bitmap_planar_context_new(DWORD flags, UINT32 max
if (!freerdp_bitmap_planar_context_reset(context, maxWidth, maxHeight))
{
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
freerdp_bitmap_planar_context_free(context);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c
index df98ad3..3ab84ef 100644
--- a/libfreerdp/codec/progressive.c
+++ b/libfreerdp/codec/progressive.c
@@ -2312,67 +2312,11 @@ static SSIZE_T progressive_parse_block(PROGRESSIVE_CONTEXT* progressive, wStream
return rc;
}
-INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize,
- BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
- UINT32 nYDst, REGION16* invalidRegion, UINT16 surfaceId,
- UINT32 frameId)
+static BOOL update_tiles(PROGRESSIVE_CONTEXT* progressive, PROGRESSIVE_SURFACE_CONTEXT* surface,
+ BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
+ UINT32 nYDst, PROGRESSIVE_BLOCK_REGION* region, REGION16* invalidRegion)
{
- INT32 rc = 1;
-
- WINPR_ASSERT(progressive);
- PROGRESSIVE_SURFACE_CONTEXT* surface = progressive_get_surface_data(progressive, surfaceId);
-
- if (!surface)
- {
- WLog_Print(progressive->log, WLOG_ERROR, "ProgressiveRegion no surface for %" PRIu16,
- surfaceId);
- return -1001;
- }
-
- PROGRESSIVE_BLOCK_REGION* region = &progressive->region;
- WINPR_ASSERT(region);
-
- if (surface->frameId != frameId)
- {
- surface->frameId = frameId;
- surface->numUpdatedTiles = 0;
- }
-
- wStream ss = { 0 };
- wStream* s = Stream_StaticConstInit(&ss, pSrcData, SrcSize);
- WINPR_ASSERT(s);
-
- switch (DstFormat)
- {
- case PIXEL_FORMAT_RGBA32:
- case PIXEL_FORMAT_RGBX32:
- case PIXEL_FORMAT_BGRA32:
- case PIXEL_FORMAT_BGRX32:
- progressive->format = DstFormat;
- break;
- default:
- progressive->format = PIXEL_FORMAT_XRGB32;
- break;
- }
-
- const size_t start = Stream_GetPosition(s);
- progressive->state = 0; /* Set state to not initialized */
- while (Stream_GetRemainingLength(s) > 0)
- {
- if (progressive_parse_block(progressive, s, surface, region) < 0)
- goto fail;
- }
-
- const size_t end = Stream_GetPosition(s);
- if ((end - start) != SrcSize)
- {
- WLog_Print(progressive->log, WLOG_ERROR,
- "total block len %" PRIuz " does not match read data %" PRIu32, end - start,
- SrcSize);
- rc = -1041;
- goto fail;
- }
-
+ BOOL rc = TRUE;
REGION16 clippingRects = { 0 };
region16_init(&clippingRects);
@@ -2425,13 +2369,11 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD
goto fail;
if (rect->top + height > surface->height)
goto fail;
- if (!freerdp_image_copy(pDstData, DstFormat, nDstStep, rect->left, rect->top, width,
+ rc = freerdp_image_copy(pDstData, DstFormat, nDstStep, rect->left, rect->top, width,
height, tile->data, progressive->format, tile->stride, nXSrc,
- nYSrc, NULL, FREERDP_KEEP_DST_ALPHA))
- {
- rc = -42;
+ nYSrc, NULL, FREERDP_KEEP_DST_ALPHA);
+ if (!rc)
break;
- }
if (invalidRegion)
region16_union_rect(invalidRegion, invalidRegion, rect);
@@ -2441,8 +2383,75 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD
tile->dirty = FALSE;
}
+fail:
region16_uninit(&clippingRects);
- surface->numUpdatedTiles = 0;
+ return rc;
+}
+
+INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize,
+ BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
+ UINT32 nYDst, REGION16* invalidRegion, UINT16 surfaceId,
+ UINT32 frameId)
+{
+ INT32 rc = 1;
+
+ WINPR_ASSERT(progressive);
+ PROGRESSIVE_SURFACE_CONTEXT* surface = progressive_get_surface_data(progressive, surfaceId);
+
+ if (!surface)
+ {
+ WLog_Print(progressive->log, WLOG_ERROR, "ProgressiveRegion no surface for %" PRIu16,
+ surfaceId);
+ return -1001;
+ }
+
+ PROGRESSIVE_BLOCK_REGION* region = &progressive->region;
+ WINPR_ASSERT(region);
+
+ if (surface->frameId != frameId)
+ {
+ surface->frameId = frameId;
+ surface->numUpdatedTiles = 0;
+ }
+
+ wStream ss = { 0 };
+ wStream* s = Stream_StaticConstInit(&ss, pSrcData, SrcSize);
+ WINPR_ASSERT(s);
+
+ switch (DstFormat)
+ {
+ case PIXEL_FORMAT_RGBA32:
+ case PIXEL_FORMAT_RGBX32:
+ case PIXEL_FORMAT_BGRA32:
+ case PIXEL_FORMAT_BGRX32:
+ progressive->format = DstFormat;
+ break;
+ default:
+ progressive->format = PIXEL_FORMAT_XRGB32;
+ break;
+ }
+
+ const size_t start = Stream_GetPosition(s);
+ progressive->state = 0; /* Set state to not initialized */
+ while (Stream_GetRemainingLength(s) > 0)
+ {
+ if (progressive_parse_block(progressive, s, surface, region) < 0)
+ goto fail;
+ }
+
+ const size_t end = Stream_GetPosition(s);
+ if ((end - start) != SrcSize)
+ {
+ WLog_Print(progressive->log, WLOG_ERROR,
+ "total block len %" PRIuz " does not match read data %" PRIu32, end - start,
+ SrcSize);
+ rc = -1041;
+ goto fail;
+ }
+
+ if (!update_tiles(progressive, surface, pDstData, DstFormat, nDstStep, nXDst, nYDst, region,
+ invalidRegion))
+ return -2002;
fail:
return rc;
}
@@ -2631,7 +2640,10 @@ PROGRESSIVE_CONTEXT* progressive_context_new_ex(BOOL Compressor, UINT32 Threadin
}
return progressive;
fail:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
progressive_context_free(progressive);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c
index 66ed1e0..c12f6d4 100644
--- a/libfreerdp/codec/rfx.c
+++ b/libfreerdp/codec/rfx.c
@@ -342,7 +342,10 @@ RFX_CONTEXT* rfx_context_new_ex(BOOL encoder, UINT32 ThreadingFlags)
context->expectedDataBlockType = WBT_FRAME_BEGIN;
return context;
fail:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
rfx_context_free(context);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/test/TestFuzzCodecs.c b/libfreerdp/codec/test/TestFuzzCodecs.c
index d83d8d4..f923765 100644
--- a/libfreerdp/codec/test/TestFuzzCodecs.c
+++ b/libfreerdp/codec/test/TestFuzzCodecs.c
@@ -453,28 +453,15 @@ int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
if (Size < 4)
return 0;
- int i = 0;
- winpr_RAND(&i, sizeof(i));
- i = i % 18;
-
- if (i < 2)
- TestFreeRDPCodecClear(Data, Size);
- else if (i < 4)
- TestFreeRDPCodecXCrush(Data, Size);
- else if (i < 6)
- TestFreeRDPCodecZGfx(Data, Size);
- else if (i < 8)
- TestFreeRDPCodecNCrush(Data, Size);
- else if (i < 10)
- TestFreeRDPCodecRemoteFX(Data, Size);
- else if (i < 12)
- TestFreeRDPCodecMppc(Data, Size);
- else if (i < 14)
- TestFreeRDPCodecProgressive(Data, Size);
- else if (i < 16)
- TestFreeRDPCodecInterleaved(Data, Size);
- else if (i < 18)
- TestFreeRDPCodecPlanar(Data, Size);
+ TestFreeRDPCodecClear(Data, Size);
+ TestFreeRDPCodecXCrush(Data, Size);
+ TestFreeRDPCodecZGfx(Data, Size);
+ TestFreeRDPCodecNCrush(Data, Size);
+ TestFreeRDPCodecRemoteFX(Data, Size);
+ TestFreeRDPCodecMppc(Data, Size);
+ TestFreeRDPCodecProgressive(Data, Size);
+ TestFreeRDPCodecInterleaved(Data, Size);
+ TestFreeRDPCodecPlanar(Data, Size);
return 0;
}
diff --git a/libfreerdp/codec/yuv.c b/libfreerdp/codec/yuv.c
index c546566..97c2374 100644
--- a/libfreerdp/codec/yuv.c
+++ b/libfreerdp/codec/yuv.c
@@ -251,7 +251,10 @@ YUV_CONTEXT* yuv_context_new(BOOL encoder, UINT32 ThreadingFlags)
return ret;
error_threadpool:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
yuv_context_free(ret);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/libfreerdp/codec/zgfx.c b/libfreerdp/codec/zgfx.c
index b7ee275..3a9d2e5 100644
--- a/libfreerdp/codec/zgfx.c
+++ b/libfreerdp/codec/zgfx.c
@@ -382,16 +382,46 @@ static BYTE* aligned_zgfx_malloc(size_t size)
return malloc(size + 64);
}
+static BOOL zgfx_append(ZGFX_CONTEXT* zgfx, BYTE** ppConcatenated, size_t uncompressedSize,
+ size_t* pUsed)
+{
+ WINPR_ASSERT(zgfx);
+ WINPR_ASSERT(ppConcatenated);
+ WINPR_ASSERT(pUsed);
+
+ const size_t used = *pUsed;
+ if (zgfx->OutputCount > UINT32_MAX - used)
+ return FALSE;
+
+ if (used + zgfx->OutputCount > uncompressedSize)
+ return FALSE;
+
+ BYTE* tmp = realloc(*ppConcatenated, used + zgfx->OutputCount + 64ull);
+ if (!tmp)
+ return FALSE;
+ *ppConcatenated = tmp;
+ CopyMemory(&tmp[used], zgfx->OutputBuffer, zgfx->OutputCount);
+ *pUsed = used + zgfx->OutputCount;
+ return TRUE;
+}
+
int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
UINT32* pDstSize, UINT32 flags)
{
int status = -1;
BYTE descriptor = 0;
wStream sbuffer = { 0 };
+ size_t used = 0;
+ BYTE* pConcatenated = NULL;
wStream* stream = Stream_StaticConstInit(&sbuffer, pSrcData, SrcSize);
WINPR_ASSERT(zgfx);
WINPR_ASSERT(stream);
+ WINPR_ASSERT(ppDstData);
+ WINPR_ASSERT(pDstSize);
+
+ *ppDstData = NULL;
+ *pDstSize = 0;
if (!Stream_CheckAndLogRequiredLength(TAG, stream, 1))
goto fail;
@@ -403,16 +433,15 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
if (!zgfx_decompress_segment(zgfx, stream, Stream_GetRemainingLength(stream)))
goto fail;
- *ppDstData = NULL;
-
if (zgfx->OutputCount > 0)
- *ppDstData = aligned_zgfx_malloc(zgfx->OutputCount);
-
- if (!*ppDstData)
- goto fail;
-
- *pDstSize = zgfx->OutputCount;
- CopyMemory(*ppDstData, zgfx->OutputBuffer, zgfx->OutputCount);
+ {
+ if (!zgfx_append(zgfx, &pConcatenated, zgfx->OutputCount, &used))
+ goto fail;
+ if (used != zgfx->OutputCount)
+ goto fail;
+ *ppDstData = pConcatenated;
+ *pDstSize = zgfx->OutputCount;
+ }
}
else if (descriptor == ZGFX_SEGMENTED_MULTIPART)
{
@@ -420,8 +449,6 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
UINT16 segmentNumber = 0;
UINT16 segmentCount = 0;
UINT32 uncompressedSize = 0;
- BYTE* pConcatenated = NULL;
- size_t used = 0;
if (!Stream_CheckAndLogRequiredLength(TAG, stream, 6))
goto fail;
@@ -429,17 +456,6 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
Stream_Read_UINT16(stream, segmentCount); /* segmentCount (2 bytes) */
Stream_Read_UINT32(stream, uncompressedSize); /* uncompressedSize (4 bytes) */
- if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, stream, segmentCount, sizeof(UINT32)))
- goto fail;
-
- pConcatenated = aligned_zgfx_malloc(uncompressedSize);
-
- if (!pConcatenated)
- goto fail;
-
- *ppDstData = pConcatenated;
- *pDstSize = uncompressedSize;
-
for (segmentNumber = 0; segmentNumber < segmentCount; segmentNumber++)
{
if (!Stream_CheckAndLogRequiredLength(TAG, stream, sizeof(UINT32)))
@@ -450,16 +466,15 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
if (!zgfx_decompress_segment(zgfx, stream, segmentSize))
goto fail;
- if (zgfx->OutputCount > UINT32_MAX - used)
+ if (!zgfx_append(zgfx, &pConcatenated, uncompressedSize, &used))
goto fail;
+ }
- if (used + zgfx->OutputCount > uncompressedSize)
- goto fail;
+ if (used != uncompressedSize)
+ goto fail;
- CopyMemory(pConcatenated, zgfx->OutputBuffer, zgfx->OutputCount);
- pConcatenated += zgfx->OutputCount;
- used += zgfx->OutputCount;
- }
+ *ppDstData = pConcatenated;
+ *pDstSize = uncompressedSize;
}
else
{
@@ -468,6 +483,8 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
status = 1;
fail:
+ if (status < 0)
+ free(pConcatenated);
return status;
}
diff --git a/libfreerdp/core/aad.c b/libfreerdp/core/aad.c
index 15eabed..00593a0 100644
--- a/libfreerdp/core/aad.c
+++ b/libfreerdp/core/aad.c
@@ -716,11 +716,11 @@ static char* bn_to_base64_url(wLog* wlog, rdpPrivateKey* key, enum FREERDP_KEY_P
WINPR_ASSERT(key);
size_t len = 0;
- char* bn = freerdp_key_get_param(key, param, &len);
+ BYTE* bn = freerdp_key_get_param(key, param, &len);
if (!bn)
return NULL;
- char* b64 = (char*)crypto_base64url_encode(bn, len);
+ char* b64 = crypto_base64url_encode(bn, len);
free(bn);
if (!b64)
diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c
index 733a763..f2d035a 100644
--- a/libfreerdp/core/gcc.c
+++ b/libfreerdp/core/gcc.c
@@ -1765,6 +1765,9 @@ static BOOL gcc_update_server_random(rdpSettings* settings)
*/
BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs)
{
+ if (!gcc_update_server_random(mcs_get_settings(mcs)))
+ return FALSE;
+
const rdpSettings* settings = mcs_get_const_settings(mcs);
WINPR_ASSERT(s);
@@ -1779,8 +1782,6 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs)
if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE)
return TRUE;
- if (!gcc_update_server_random(settings))
- return FALSE;
if (!Stream_EnsureRemainingCapacity(s, sizeof(UINT32) + settings->ServerRandomLength))
return FALSE;
diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c
index 7d6eec1..3395e4d 100644
--- a/libfreerdp/core/info.c
+++ b/libfreerdp/core/info.c
@@ -1398,6 +1398,10 @@ static BOOL rdp_write_logon_info_v1(wStream* s, logon_info* info)
return FALSE;
/* domain */
+ WINPR_ASSERT(info);
+ if (!info->domain || !info->username)
+ return FALSE;
+
len = strnlen(info->domain, charLen + 1);
if (len > charLen)
return FALSE;
diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c
index 855b700..bef1b45 100644
--- a/libfreerdp/core/orders.c
+++ b/libfreerdp/core/orders.c
@@ -797,9 +797,11 @@ static INLINE BOOL update_write_4byte_unsigned(wStream* s, UINT32 value)
return TRUE;
}
+
static INLINE BOOL update_read_delta(wStream* s, INT32* value)
{
BYTE byte = 0;
+ UINT32 uvalue = 0;
if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
return FALSE;
@@ -807,9 +809,9 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value)
Stream_Read_UINT8(s, byte);
if (byte & 0x40)
- *value = (byte | ~0x3F);
+ uvalue = (byte | ~0x3F);
else
- *value = (byte & 0x3F);
+ uvalue = (byte & 0x3F);
if (byte & 0x80)
{
@@ -817,8 +819,9 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value)
return FALSE;
Stream_Read_UINT8(s, byte);
- *value = (*value << 8) | byte;
+ uvalue = (uvalue << 8) | byte;
}
+ *value = (INT32)uvalue;
return TRUE;
}
@@ -2171,7 +2174,9 @@ static BOOL update_read_ellipse_cb_order(const char* orderName, wStream* s,
return TRUE;
return FALSE;
}
+
/* Secondary Drawing Orders */
+WINPR_ATTR_MALLOC(free_cache_bitmap_order, 2)
static CACHE_BITMAP_ORDER* update_read_cache_bitmap_order(rdpUpdate* update, wStream* s,
BOOL compressed, UINT16 flags)
{
@@ -2290,6 +2295,7 @@ BOOL update_write_cache_bitmap_order(wStream* s, const CACHE_BITMAP_ORDER* cache
return TRUE;
}
+WINPR_ATTR_MALLOC(free_cache_bitmap_v2_order, 2)
static CACHE_BITMAP_V2_ORDER* update_read_cache_bitmap_v2_order(rdpUpdate* update, wStream* s,
BOOL compressed, UINT16 flags)
{
@@ -2466,6 +2472,8 @@ BOOL update_write_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache
cache_bitmap_v2->compressed = compressed;
return TRUE;
}
+
+WINPR_ATTR_MALLOC(free_cache_bitmap_v3_order, 2)
static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* update, wStream* s,
UINT16 flags)
{
@@ -2571,6 +2579,8 @@ BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache
Stream_Write(s, bitmapData->data, bitmapData->length);
return TRUE;
}
+
+WINPR_ATTR_MALLOC(free_cache_color_table_order, 2)
static CACHE_COLOR_TABLE_ORDER* update_read_cache_color_table_order(rdpUpdate* update, wStream* s,
UINT16 flags)
{
diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c
index 42c4c21..fba9281 100644
--- a/libfreerdp/core/peer.c
+++ b/libfreerdp/core/peer.c
@@ -1532,6 +1532,7 @@ BOOL freerdp_peer_context_new_ex(freerdp_peer* client, const rdpSettings* settin
if (!client)
return FALSE;
+ WINPR_ASSERT(client->ContextSize >= sizeof(rdpContext));
if (!(context = (rdpContext*)calloc(1, client->ContextSize)))
goto fail;
diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c
index 8538a90..5343a07 100644
--- a/libfreerdp/core/redirection.c
+++ b/libfreerdp/core/redirection.c
@@ -243,7 +243,7 @@ static BOOL rdp_redirection_read_base64_wchar(UINT32 flag, wStream* s, UINT32* p
const WCHAR* wchar = (const WCHAR*)ptr;
size_t utf8_len = 0;
- char* utf8 = ConvertWCharNToUtf8Alloc(wchar, *pLength, &utf8_len);
+ char* utf8 = ConvertWCharNToUtf8Alloc(wchar, *pLength / sizeof(WCHAR), &utf8_len);
if (!utf8)
goto fail;
diff --git a/libfreerdp/core/test/CMakeLists.txt b/libfreerdp/core/test/CMakeLists.txt
index ebd8fef..9b2e654 100644
--- a/libfreerdp/core/test/CMakeLists.txt
+++ b/libfreerdp/core/test/CMakeLists.txt
@@ -10,7 +10,9 @@ set(${MODULE_PREFIX}_TESTS
TestSettings.c)
set(FUZZERS
- TestFuzzCryptoCertificateDataSetPEM.c
+ TestFuzzCoreClient.c
+ TestFuzzCoreServer.c
+ TestFuzzCryptoCertificateDataSetPEM.c
)
if(WITH_SAMPLE AND WITH_SERVER AND NOT WIN32)
@@ -34,7 +36,7 @@ add_definitions(-DTESTING_SRC_DIRECTORY="${PROJECT_SOURCE_DIR}")
target_link_libraries(${MODULE_NAME} freerdp winpr freerdp-client)
include (AddFuzzerTest)
-add_fuzzer_test("${FUZZERS}" "freerdp winpr")
+add_fuzzer_test("${FUZZERS}" "freerdp-client freerdp winpr")
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
@@ -44,4 +46,3 @@ foreach(test ${${MODULE_PREFIX}_TESTS})
endforeach()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Core/Test")
-
diff --git a/libfreerdp/core/test/TestFuzzCoreClient.c b/libfreerdp/core/test/TestFuzzCoreClient.c
new file mode 100644
index 0000000..5c67497
--- /dev/null
+++ b/libfreerdp/core/test/TestFuzzCoreClient.c
@@ -0,0 +1,116 @@
+#include <freerdp/client.h>
+
+#include "../fastpath.h"
+#include "../surface.h"
+#include "../window.h"
+#include "../info.h"
+#include "../multitransport.h"
+
+static BOOL test_client(const uint8_t* Data, size_t Size)
+{
+ RDP_CLIENT_ENTRY_POINTS entry = { 0 };
+
+ entry.Version = RDP_CLIENT_INTERFACE_VERSION;
+ entry.Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
+ entry.ContextSize = sizeof(rdpContext);
+
+ rdpContext* context = freerdp_client_context_new(&entry);
+ if (!context)
+ goto fail;
+
+ rdpRdp* rdp = context->rdp;
+ WINPR_ASSERT(rdp);
+
+ wStream sbuffer = { 0 };
+ wStream* s = Stream_StaticConstInit(&sbuffer, Data, Size);
+
+ {
+ rdpFastPath* fastpath = rdp->fastpath;
+ WINPR_ASSERT(fastpath);
+
+ fastpath_recv_updates(fastpath, s);
+ fastpath_recv_inputs(fastpath, s);
+
+ UINT16 length = 0;
+ fastpath_read_header_rdp(fastpath, s, &length);
+ fastpath_decrypt(fastpath, s, &length);
+ }
+
+ {
+ UINT16 length = 0;
+ UINT16 flags = 0;
+ UINT16 channelId = 0;
+ UINT16 tpktLength = 0;
+ UINT16 remainingLength = 0;
+ UINT16 type = 0;
+ UINT16 securityFlags = 0;
+ UINT32 share_id = 0;
+ BYTE compressed_type = 0;
+ BYTE btype = 0;
+ UINT16 compressed_len = 0;
+
+ rdp_recv_callback(rdp->transport, s, rdp);
+ rdp_read_security_header(rdp, s, &flags, &length);
+ rdp_read_header(rdp, s, &length, &channelId);
+ rdp_read_share_control_header(rdp, s, &tpktLength, &remainingLength, &type, &channelId);
+ rdp_read_share_data_header(rdp, s, &length, &btype, &share_id, &compressed_type,
+ &compressed_len);
+ rdp_recv_enhanced_security_redirection_packet(rdp, s);
+ rdp_recv_out_of_sequence_pdu(rdp, s, type, length);
+ rdp_recv_message_channel_pdu(rdp, s, securityFlags);
+ }
+ {
+ rdpUpdate* update = rdp->update;
+ UINT16 channelId = 0;
+ UINT16 length = 0;
+ UINT16 pduSource = 0;
+ UINT16 pduLength = 0;
+ update_recv_order(update, s);
+ update_recv_altsec_window_order(update, s);
+ update_recv_play_sound(update, s);
+ update_recv_pointer(update, s);
+ update_recv_surfcmds(update, s);
+ rdp_recv_get_active_header(rdp, s, &channelId, &length);
+ rdp_recv_demand_active(rdp, s, pduSource, length);
+ rdp_recv_confirm_active(rdp, s, pduLength);
+ }
+ {
+ rdpNla* nla = nla_new(rdp->context, rdp->transport);
+ nla_recv_pdu(nla, s);
+ nla_free(nla);
+ }
+ {
+ rdp_recv_heartbeat_packet(rdp, s);
+ rdp->state = CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE;
+ rdp_recv_client_info(rdp, s);
+ rdp_recv_save_session_info(rdp, s);
+ }
+ {
+ freerdp_is_valid_mcs_create_request(Data, Size);
+ freerdp_is_valid_mcs_create_response(Data, Size);
+ }
+ {
+ multitransport_recv_request(rdp->multitransport, s);
+ multitransport_recv_response(rdp->multitransport, s);
+ }
+ {
+ autodetect_recv_request_packet(rdp->autodetect, RDP_TRANSPORT_TCP, s);
+ autodetect_recv_response_packet(rdp->autodetect, RDP_TRANSPORT_TCP, s);
+ }
+ {
+ rdp_recv_deactivate_all(rdp, s);
+ rdp_recv_server_synchronize_pdu(rdp, s);
+ rdp_recv_client_synchronize_pdu(rdp, s);
+
+ rdp_recv_data_pdu(rdp, s);
+ rdp_recv_font_map_pdu(rdp, s);
+ }
+fail:
+ freerdp_client_context_free(context);
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
+{
+ test_client(Data, Size);
+ return 0;
+}
diff --git a/libfreerdp/core/test/TestFuzzCoreServer.c b/libfreerdp/core/test/TestFuzzCoreServer.c
new file mode 100644
index 0000000..cd469f4
--- /dev/null
+++ b/libfreerdp/core/test/TestFuzzCoreServer.c
@@ -0,0 +1,108 @@
+#include <freerdp/peer.h>
+
+#include "../fastpath.h"
+#include "../surface.h"
+#include "../window.h"
+#include "../info.h"
+#include "../multitransport.h"
+
+static BOOL test_server(const uint8_t* Data, size_t Size)
+{
+ freerdp_peer* client = calloc(1, sizeof(freerdp_peer));
+ if (!client)
+ goto fail;
+ client->ContextSize = sizeof(rdpContext);
+ if (!freerdp_peer_context_new(client))
+ goto fail;
+
+ WINPR_ASSERT(client->context);
+ rdpRdp* rdp = client->context->rdp;
+ WINPR_ASSERT(rdp);
+
+ wStream sbuffer = { 0 };
+ wStream* s = Stream_StaticConstInit(&sbuffer, Data, Size);
+
+ {
+ rdpFastPath* fastpath = rdp->fastpath;
+ WINPR_ASSERT(fastpath);
+
+ fastpath_recv_updates(fastpath, s);
+ fastpath_recv_inputs(fastpath, s);
+
+ UINT16 length = 0;
+ fastpath_read_header_rdp(fastpath, s, &length);
+ fastpath_decrypt(fastpath, s, &length);
+ }
+
+ {
+ UINT16 length = 0;
+ UINT16 flags = 0;
+ UINT16 channelId = 0;
+ UINT16 tpktLength = 0;
+ UINT16 remainingLength = 0;
+ UINT16 type = 0;
+ UINT16 securityFlags = 0;
+ UINT32 share_id = 0;
+ BYTE compressed_type = 0;
+ BYTE btype = 0;
+ UINT16 compressed_len = 0;
+ rdp_read_security_header(rdp, s, &flags, &length);
+ rdp_read_header(rdp, s, &length, &channelId);
+ rdp_read_share_control_header(rdp, s, &tpktLength, &remainingLength, &type, &channelId);
+ rdp_read_share_data_header(rdp, s, &length, &btype, &share_id, &compressed_type,
+ &compressed_len);
+ rdp_recv_message_channel_pdu(rdp, s, securityFlags);
+ }
+ {
+ rdpUpdate* update = rdp->update;
+ UINT16 channelId = 0;
+ UINT16 length = 0;
+ UINT16 pduSource = 0;
+ UINT16 pduLength = 0;
+ update_recv_order(update, s);
+ update_recv_altsec_window_order(update, s);
+ update_recv_play_sound(update, s);
+ update_recv_pointer(update, s);
+ update_recv_surfcmds(update, s);
+ rdp_recv_get_active_header(rdp, s, &channelId, &length);
+ rdp_recv_demand_active(rdp, s, pduSource, length);
+ rdp_recv_confirm_active(rdp, s, pduLength);
+ }
+ {
+ rdpNla* nla = nla_new(rdp->context, rdp->transport);
+ nla_recv_pdu(nla, s);
+ nla_free(nla);
+ }
+ {
+ rdp_recv_heartbeat_packet(rdp, s);
+ rdp->state = CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE;
+ rdp_recv_client_info(rdp, s);
+ rdp_recv_save_session_info(rdp, s);
+ }
+ {
+ freerdp_is_valid_mcs_create_request(Data, Size);
+ freerdp_is_valid_mcs_create_response(Data, Size);
+ }
+ {
+ multitransport_recv_request(rdp->multitransport, s);
+ multitransport_recv_response(rdp->multitransport, s);
+ }
+ {
+ autodetect_recv_request_packet(rdp->autodetect, RDP_TRANSPORT_TCP, s);
+ autodetect_recv_response_packet(rdp->autodetect, RDP_TRANSPORT_TCP, s);
+ }
+ {
+ rdp_recv_deactivate_all(rdp, s);
+ rdp_recv_server_synchronize_pdu(rdp, s);
+ rdp_recv_client_synchronize_pdu(rdp, s);
+ }
+fail:
+ freerdp_peer_context_free(client);
+ free(client);
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
+{
+ test_server(Data, Size);
+ return 0;
+}
diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c
index cfc0abc..9e79863 100644
--- a/libfreerdp/core/update.c
+++ b/libfreerdp/core/update.c
@@ -2031,7 +2031,9 @@ static BOOL update_send_cache_brush(rdpContext* context, const CACHE_BRUSH_ORDER
return FALSE;
const size_t em = Stream_GetPosition(s);
- WINPR_ASSERT(em > bm + 13);
+ if (em <= bm + 13)
+ return FALSE;
+
const size_t orderLength = (em - bm) - 13;
WINPR_ASSERT(orderLength <= UINT16_MAX);
Stream_SetPosition(s, bm);
@@ -3299,6 +3301,9 @@ void update_free(rdpUpdate* update)
MessageQueue_Free(up->queue);
DeleteCriticalSection(&up->mux);
+
+ if (up->us)
+ Stream_Free(up->us, TRUE);
free(update);
}
}
@@ -3328,7 +3333,9 @@ BOOL update_begin_paint(rdpUpdate* update)
/* Reset the invalid regions, we start a new frame here. */
rdpGdi* gdi = update->context->gdi;
- WINPR_ASSERT(gdi);
+ if (!gdi)
+ return FALSE;
+
if (gdi->hdc && gdi->primary && gdi->primary->hdc)
{
HGDI_WND hwnd = gdi->primary->hdc->hwnd;
diff --git a/libfreerdp/crypto/privatekey.c b/libfreerdp/crypto/privatekey.c
index 55379d4..9a6fb25 100644
--- a/libfreerdp/crypto/privatekey.c
+++ b/libfreerdp/crypto/privatekey.c
@@ -442,7 +442,7 @@ fail:
return rc;
}
-char* freerdp_key_get_param(const rdpPrivateKey* key, enum FREERDP_KEY_PARAM param, size_t* plength)
+BYTE* freerdp_key_get_param(const rdpPrivateKey* key, enum FREERDP_KEY_PARAM param, size_t* plength)
{
BYTE* buf = NULL;
@@ -527,7 +527,7 @@ char* freerdp_key_get_param(const rdpPrivateKey* key, enum FREERDP_KEY_PARAM par
fail:
BN_free(bn);
- return (char*)buf;
+ return buf;
}
WINPR_DIGEST_CTX* freerdp_key_digest_sign(rdpPrivateKey* key, WINPR_MD_TYPE digest)
diff --git a/libfreerdp/crypto/privatekey.h b/libfreerdp/crypto/privatekey.h
index 418abf5..b423c9a 100644
--- a/libfreerdp/crypto/privatekey.h
+++ b/libfreerdp/crypto/privatekey.h
@@ -52,7 +52,7 @@ extern "C"
*/
FREERDP_LOCAL EVP_PKEY* freerdp_key_get_evp_pkey(const rdpPrivateKey* key);
- FREERDP_LOCAL char* freerdp_key_get_param(const rdpPrivateKey* key,
+ FREERDP_LOCAL BYTE* freerdp_key_get_param(const rdpPrivateKey* key,
enum FREERDP_KEY_PARAM param, size_t* plength);
FREERDP_LOCAL WINPR_DIGEST_CTX* freerdp_key_digest_sign(rdpPrivateKey* key,
diff --git a/libfreerdp/emu/scard/smartcard_emulate.c b/libfreerdp/emu/scard/smartcard_emulate.c
index d517bd6..6e21f17 100644
--- a/libfreerdp/emu/scard/smartcard_emulate.c
+++ b/libfreerdp/emu/scard/smartcard_emulate.c
@@ -38,8 +38,8 @@
#define MAX_CACHE_ITEM_SIZE 4096
#define MAX_CACHE_ITEM_VALUES 4096
-static const CHAR g_ReaderNameA[] = { 'F', 'r', 'e', 'e', 'R', 'D', 'P', ' ', 'E',
- 'm', 'u', 'l', 'a', 't', 'o', 'r', '\0', '\0' };
+static CHAR g_ReaderNameA[] = { 'F', 'r', 'e', 'e', 'R', 'D', 'P', ' ', 'E',
+ 'm', 'u', 'l', 'a', 't', 'o', 'r', '\0', '\0' };
static INIT_ONCE g_ReaderNameWGuard = INIT_ONCE_STATIC_INIT;
static WCHAR g_ReaderNameW[32] = { 0 };
static size_t g_ReaderNameWLen = 0;
diff --git a/libfreerdp/gdi/test/TestGdiCreate.c b/libfreerdp/gdi/test/TestGdiCreate.c
index c71b396..e6594ea 100644
--- a/libfreerdp/gdi/test/TestGdiCreate.c
+++ b/libfreerdp/gdi/test/TestGdiCreate.c
@@ -124,7 +124,7 @@ fail:
if (hBitmap)
gdi_DeleteObject((HGDIOBJECT)hBitmap);
else
- free(data);
+ winpr_aligned_free(data);
return rc;
}
diff --git a/libfreerdp/primitives/test/TestPrimitivesYCoCg.c b/libfreerdp/primitives/test/TestPrimitivesYCoCg.c
index 318aec6..10a8754 100644
--- a/libfreerdp/primitives/test/TestPrimitivesYCoCg.c
+++ b/libfreerdp/primitives/test/TestPrimitivesYCoCg.c
@@ -76,7 +76,7 @@ static BOOL test_YCoCgRToRGB_8u_AC4R_func(UINT32 width, UINT32 height)
if (c != sse)
{
- printf("optimized->YCoCgRToRGB FAIL[%s] [%" PRIu32 "]: 0x%08" PRIx32
+ printf("optimized->YCoCgRToRGB FAIL[%s] [%" PRIuz "]: 0x%08" PRIx32
" -> C 0x%08" PRIx32 " vs optimized 0x%08" PRIx32 "\n",
formatName, i, in[i + 1], c, sse);
status = -1;
diff --git a/server/shadow/shadow.c b/server/shadow/shadow.c
index 14c9014..717128c 100644
--- a/server/shadow/shadow.c
+++ b/server/shadow/shadow.c
@@ -54,7 +54,7 @@ int main(int argc, char** argv)
"maximum connections allowed to server, 0 to deactivate" },
{ "rect", COMMAND_LINE_VALUE_REQUIRED, "<x,y,w,h>", NULL, NULL, -1, NULL,
"Select rectangle within monitor to share" },
- { "auth", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
+ { "auth", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
"Clients must authenticate" },
{ "remote-guard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
"Remote credential guard" },
diff --git a/winpr/CMakeLists.txt b/winpr/CMakeLists.txt
index f06aaf7..9c8eced 100644
--- a/winpr/CMakeLists.txt
+++ b/winpr/CMakeLists.txt
@@ -137,7 +137,7 @@ endif()
# Soname versioning
set(VERSION_REGEX "^(.*)([0-9]+)\\.([0-9]+)\\.([0-9]+)-?(.*)")
-set(RAW_VERSION_STRING "3.5.0")
+set(RAW_VERSION_STRING "3.5.1")
if(EXISTS "${PROJECT_SOURCE_DIR}/.source_tag")
file(READ ${PROJECT_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
elseif(USE_VERSION_FROM_GIT_TAG)
diff --git a/winpr/libwinpr/clipboard/synthetic.c b/winpr/libwinpr/clipboard/synthetic.c
index db8af71..cae5106 100644
--- a/winpr/libwinpr/clipboard/synthetic.c
+++ b/winpr/libwinpr/clipboard/synthetic.c
@@ -379,7 +379,7 @@ static void* clipboard_synthesize_image_format_to_bmp(wClipboard* clipboard, UIN
WINPR_ASSERT(data);
WINPR_ASSERT(pSize);
- void* dst = NULL;
+ BYTE* dst = NULL;
const UINT32 SrcSize = *pSize;
size_t size = 0;
wImage* image = winpr_image_new();
diff --git a/winpr/libwinpr/clipboard/synthetic_file.c b/winpr/libwinpr/clipboard/synthetic_file.c
index 9a1084b..4290d2a 100644
--- a/winpr/libwinpr/clipboard/synthetic_file.c
+++ b/winpr/libwinpr/clipboard/synthetic_file.c
@@ -1105,8 +1105,8 @@ static UINT file_get_range(struct synthetic_file* file, UINT64 offset, UINT32 si
if (!GetFileInformationByHandle(file->fd, &FileInfo))
{
- file->fd = INVALID_HANDLE_VALUE;
CloseHandle(file->fd);
+ file->fd = INVALID_HANDLE_VALUE;
error = GetLastError();
WLog_ERR(TAG, "Get file [%s] information fail: 0x%08" PRIx32, file->local_name, error);
return error;
diff --git a/winpr/libwinpr/comm/comm.c b/winpr/libwinpr/comm/comm.c
index cd68a40..f891ca7 100644
--- a/winpr/libwinpr/comm/comm.c
+++ b/winpr/libwinpr/comm/comm.c
@@ -1343,7 +1343,10 @@ HANDLE CommCreateFileA(LPCSTR lpDeviceName, DWORD dwDesiredAccess, DWORD dwShare
return (HANDLE)pComm;
error_handle:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
CloseHandle(pComm);
+ WINPR_PRAGMA_DIAG_POP
return INVALID_HANDLE_VALUE;
}
diff --git a/winpr/libwinpr/crt/test/TestUnicodeConversion.c b/winpr/libwinpr/crt/test/TestUnicodeConversion.c
index 187a068..eb0acb7 100644
--- a/winpr/libwinpr/crt/test/TestUnicodeConversion.c
+++ b/winpr/libwinpr/crt/test/TestUnicodeConversion.c
@@ -15,9 +15,9 @@
typedef struct
{
- char* utf8;
+ const char* utf8;
size_t utf8len;
- WCHAR* utf16;
+ const WCHAR* utf16;
size_t utf16len;
} testcase_t;
diff --git a/winpr/libwinpr/file/generic.c b/winpr/libwinpr/file/generic.c
index 9318586..e7bc0cf 100644
--- a/winpr/libwinpr/file/generic.c
+++ b/winpr/libwinpr/file/generic.c
@@ -925,7 +925,10 @@ static WIN32_FILE_SEARCH* file_search_new(const char* name, size_t namelen, cons
return pFileSearch;
fail:
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
FindClose(pFileSearch);
+ WINPR_PRAGMA_DIAG_POP
return NULL;
}
diff --git a/winpr/libwinpr/file/test/TestFileFindFirstFile.c b/winpr/libwinpr/file/test/TestFileFindFirstFile.c
index 04829a3..0e5de44 100644
--- a/winpr/libwinpr/file/test/TestFileFindFirstFile.c
+++ b/winpr/libwinpr/file/test/TestFileFindFirstFile.c
@@ -98,7 +98,8 @@ static BOOL find_first_file_success(const char* FilePath)
}
rc = TRUE;
fail:
- FindClose(hFind);
+ if (hFind != INVALID_HANDLE_VALUE)
+ FindClose(hFind);
return rc;
}
diff --git a/winpr/libwinpr/sspi/Kerberos/kerberos.c b/winpr/libwinpr/sspi/Kerberos/kerberos.c
index 3cf7786..cba8038 100644
--- a/winpr/libwinpr/sspi/Kerberos/kerberos.c
+++ b/winpr/libwinpr/sspi/Kerberos/kerberos.c
@@ -1496,7 +1496,7 @@ static SECURITY_STATUS SEC_ENTRY kerberos_EncryptMessage(PCtxtHandle phContext,
KRB_CONTEXT* context = get_context(phContext);
PSecBuffer sig_buffer = NULL;
PSecBuffer data_buffer = NULL;
- BYTE* header = NULL;
+ char* header = NULL;
BYTE flags = 0;
krb5glue_key key = NULL;
krb5_keyusage usage = 0;
@@ -1547,15 +1547,15 @@ static SECURITY_STATUS SEC_ENTRY kerberos_EncryptMessage(PCtxtHandle phContext,
/* Set up the iov array in sig_buffer */
header = sig_buffer->pvBuffer;
encrypt_iov[2].data.data = header + 16;
- encrypt_iov[3].data.data = (BYTE*)encrypt_iov[2].data.data + encrypt_iov[2].data.length;
- encrypt_iov[4].data.data = (BYTE*)encrypt_iov[3].data.data + encrypt_iov[3].data.length;
- encrypt_iov[0].data.data = (BYTE*)encrypt_iov[4].data.data + encrypt_iov[4].data.length;
+ encrypt_iov[3].data.data = encrypt_iov[2].data.data + encrypt_iov[2].data.length;
+ encrypt_iov[4].data.data = encrypt_iov[3].data.data + encrypt_iov[3].data.length;
+ encrypt_iov[0].data.data = encrypt_iov[4].data.data + encrypt_iov[4].data.length;
encrypt_iov[1].data.data = data_buffer->pvBuffer;
/* Write the GSS header with 0 in RRC */
Data_Write_UINT16_BE(header, TOK_ID_WRAP);
header[2] = flags;
- header[3] = 0xFF;
+ header[3] = (char)0xFF;
Data_Write_UINT32(header + 4, 0);
Data_Write_UINT64_BE(header + 8, (context->local_seq + MessageSeqNo));
@@ -1656,8 +1656,8 @@ static SECURITY_STATUS SEC_ENTRY kerberos_DecryptMessage(PCtxtHandle phContext,
iov[0].data.data = header + 16 + rrc + ec;
iov[1].data.data = data_buffer->pvBuffer;
iov[2].data.data = header + 16 + ec;
- iov[3].data.data = (BYTE*)iov[2].data.data + iov[2].data.length;
- iov[4].data.data = (BYTE*)iov[3].data.data + iov[3].data.length;
+ iov[3].data.data = iov[2].data.data + iov[2].data.length;
+ iov[4].data.data = iov[3].data.data + iov[3].data.length;
if (krb_log_exec(krb5glue_decrypt_iov, context->ctx, key, usage, iov, ARRAYSIZE(iov)))
return SEC_E_INTERNAL_ERROR;
diff --git a/winpr/libwinpr/timezone/timezone.c b/winpr/libwinpr/timezone/timezone.c
index 6ca3e54..a727d67 100644
--- a/winpr/libwinpr/timezone/timezone.c
+++ b/winpr/libwinpr/timezone/timezone.c
@@ -23,6 +23,7 @@
#include <winpr/wtypes.h>
#include <winpr/timezone.h>
#include <winpr/crt.h>
+#include <winpr/assert.h>
#include <winpr/file.h>
#include "../log.h"
@@ -308,6 +309,11 @@ static TIME_ZONE_ENTRY* winpr_detect_windows_time_zone(void)
free(tzid);
tzid = NULL;
}
+ else if (tzid[0] == ':')
+ {
+ /* Remove leading colon, see tzset(3) */
+ memmove(tzid, tzid + 1, nSize - sizeof(char));
+ }
}
if (tzid == NULL)
@@ -323,7 +329,14 @@ static TIME_ZONE_ENTRY* winpr_detect_windows_time_zone(void)
char buf[1024] = { 0 };
const char* links[] = { buf };
- snprintf(buf, ARRAYSIZE(buf), "%s%s", zipath, tzid);
+ if (tzid[0] == '/')
+ {
+ /* Full path given in TZ */
+ links[0] = tzid;
+ }
+ else
+ snprintf(buf, ARRAYSIZE(buf), "%s%s", zipath, tzid);
+
ntzid = winpr_get_timezone_from_link(links, 1);
if (ntzid != NULL)
{
@@ -390,17 +403,20 @@ winpr_get_current_time_zone_rule(const TIME_ZONE_RULE_ENTRY* rules, UINT32 count
DWORD GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
{
time_t t = 0;
- struct tm tres;
- struct tm* local_time = NULL;
+ struct tm tres = { 0 };
TIME_ZONE_ENTRY* dtz = NULL;
+ const TIME_ZONE_INFORMATION empty = { 0 };
LPTIME_ZONE_INFORMATION tz = lpTimeZoneInformation;
- lpTimeZoneInformation->StandardBias = 0;
- time(&t);
- local_time = localtime_r(&t, &tres);
+
+ WINPR_ASSERT(tz);
+
+ *tz = empty;
+
+ t = time(NULL);
+ struct tm* local_time = localtime_r(&t, &tres);
if (!local_time)
goto out_error;
- memset(tz, 0, sizeof(TIME_ZONE_INFORMATION));
#ifdef WINPR_HAVE_TM_GMTOFF
{
long bias = -(local_time->tm_gmtoff / 60L);
@@ -410,19 +426,14 @@ DWORD GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
tz->Bias = (LONG)bias;
}
-#else
- tz->Bias = 0;
#endif
dtz = winpr_detect_windows_time_zone();
if (dtz != NULL)
{
- const TIME_ZONE_INFORMATION empty = { 0 };
-
WLog_DBG(TAG, "tz: Bias=%" PRId32 " sn='%s' dln='%s'", dtz->Bias, dtz->StandardName,
dtz->DaylightName);
- *tz = empty;
tz->Bias = dtz->Bias;
if (ConvertUtf8ToWChar(dtz->StandardName, tz->StandardName, ARRAYSIZE(tz->StandardName)) <
@@ -462,8 +473,9 @@ DWORD GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
WLog_DBG(TAG, "tz not found, using computed bias %" PRId32 ".", tz->Bias);
out_error:
free(dtz);
- memcpy(tz->StandardName, L"Client Local Time", sizeof(tz->StandardName));
- memcpy(tz->DaylightName, L"Client Local Time", sizeof(tz->DaylightName));
+ if (ConvertUtf8ToWChar("Client Local Time", tz->StandardName, ARRAYSIZE(tz->StandardName)) <= 0)
+ WLog_WARN(TAG, "Failed to set default timezone name");
+ memcpy(tz->DaylightName, tz->StandardName, sizeof(tz->DaylightName));
return 0; /* TIME_ZONE_ID_UNKNOWN */
}
diff --git a/winpr/libwinpr/utils/debug.c b/winpr/libwinpr/utils/debug.c
index a7c9a13..42d916e 100644
--- a/winpr/libwinpr/utils/debug.c
+++ b/winpr/libwinpr/utils/debug.c
@@ -161,7 +161,7 @@ char** winpr_backtrace_symbols(void* buffer, size_t* used)
*msgptr = msg;
strncpy(msg, support_msg, len);
*used = 1;
- return ppmsg;
+ return msgptr;
#endif
}
diff --git a/winpr/libwinpr/utils/image.c b/winpr/libwinpr/utils/image.c
index cc2e2ad..c609825 100644
--- a/winpr/libwinpr/utils/image.c
+++ b/winpr/libwinpr/utils/image.c
@@ -52,12 +52,12 @@
#include "../log.h"
#define TAG WINPR_TAG("utils.image")
-static SSIZE_T winpr_convert_from_jpeg(const char* comp_data, size_t comp_data_bytes, UINT32* width,
- UINT32* height, UINT32* bpp, char** ppdecomp_data);
-static SSIZE_T winpr_convert_from_png(const char* comp_data, size_t comp_data_bytes, UINT32* width,
- UINT32* height, UINT32* bpp, char** ppdecomp_data);
-static SSIZE_T winpr_convert_from_webp(const char* comp_data, size_t comp_data_bytes, UINT32* width,
- UINT32* height, UINT32* bpp, char** ppdecomp_data);
+static SSIZE_T winpr_convert_from_jpeg(const BYTE* comp_data, size_t comp_data_bytes, UINT32* width,
+ UINT32* height, UINT32* bpp, BYTE** ppdecomp_data);
+static SSIZE_T winpr_convert_from_png(const BYTE* comp_data, size_t comp_data_bytes, UINT32* width,
+ UINT32* height, UINT32* bpp, BYTE** ppdecomp_data);
+static SSIZE_T winpr_convert_from_webp(const BYTE* comp_data, size_t comp_data_bytes, UINT32* width,
+ UINT32* height, UINT32* bpp, BYTE** ppdecomp_data);
static BOOL writeBitmapFileHeader(wStream* s, const WINPR_BITMAP_FILE_HEADER* bf)
{
@@ -484,7 +484,7 @@ int winpr_image_read(wImage* image, const char* filename)
if (pos > 0)
{
- char* buffer = malloc((size_t)pos);
+ BYTE* buffer = malloc((size_t)pos);
if (buffer)
{
size_t r = fread(buffer, 1, (size_t)pos, fp);
@@ -518,9 +518,8 @@ int winpr_image_read_buffer(wImage* image, const BYTE* buffer, size_t size)
(sig[8] == 'W') && (sig[9] == 'E') && (sig[10] == 'B') && (sig[11] == 'P'))
{
image->type = WINPR_IMAGE_WEBP;
- const SSIZE_T rc =
- winpr_convert_from_webp((const char*)buffer, size, &image->width, &image->height,
- &image->bitsPerPixel, ((char**)&image->data));
+ const SSIZE_T rc = winpr_convert_from_webp(buffer, size, &image->width, &image->height,
+ &image->bitsPerPixel, &image->data);
if (rc >= 0)
{
image->bytesPerPixel = (image->bitsPerPixel + 7) / 8;
@@ -533,9 +532,8 @@ int winpr_image_read_buffer(wImage* image, const BYTE* buffer, size_t size)
(sig[10] == 0x00))
{
image->type = WINPR_IMAGE_JPEG;
- const SSIZE_T rc =
- winpr_convert_from_jpeg((const char*)buffer, size, &image->width, &image->height,
- &image->bitsPerPixel, ((char**)&image->data));
+ const SSIZE_T rc = winpr_convert_from_jpeg(buffer, size, &image->width, &image->height,
+ &image->bitsPerPixel, &image->data);
if (rc >= 0)
{
image->bytesPerPixel = (image->bitsPerPixel + 7) / 8;
@@ -547,9 +545,8 @@ int winpr_image_read_buffer(wImage* image, const BYTE* buffer, size_t size)
(sig[4] == '\r') && (sig[5] == '\n') && (sig[6] == 0x1A) && (sig[7] == '\n'))
{
image->type = WINPR_IMAGE_PNG;
- const SSIZE_T rc =
- winpr_convert_from_png((const char*)buffer, size, &image->width, &image->height,
- &image->bitsPerPixel, ((char**)&image->data));
+ const SSIZE_T rc = winpr_convert_from_png(buffer, size, &image->width, &image->height,
+ &image->bitsPerPixel, &image->data);
if (rc >= 0)
{
image->bytesPerPixel = (image->bitsPerPixel + 7) / 8;
@@ -625,11 +622,11 @@ void* winpr_convert_to_jpeg(const void* data, size_t size, UINT32 width, UINT32
jpeg_start_compress(&cinfo, TRUE);
- const unsigned char* cdata = data;
+ const JSAMPLE* cdata = data;
for (size_t x = 0; x < height; x++)
{
const JDIMENSION offset = x * stride;
- const JSAMPROW coffset = &cdata[offset];
+ const JSAMPLE* coffset = &cdata[offset];
if (jpeg_write_scanlines(&cinfo, &coffset, 1) != 1)
goto fail;
}
@@ -643,8 +640,8 @@ fail:
#endif
}
-SSIZE_T winpr_convert_from_jpeg(const char* comp_data, size_t comp_data_bytes, UINT32* width,
- UINT32* height, UINT32* bpp, char** ppdecomp_data)
+SSIZE_T winpr_convert_from_jpeg(const BYTE* comp_data, size_t comp_data_bytes, UINT32* width,
+ UINT32* height, UINT32* bpp, BYTE** ppdecomp_data)
{
WINPR_ASSERT(comp_data || (comp_data_bytes == 0));
WINPR_ASSERT(width);
@@ -658,7 +655,7 @@ SSIZE_T winpr_convert_from_jpeg(const char* comp_data, size_t comp_data_bytes, U
struct jpeg_decompress_struct cinfo = { 0 };
struct jpeg_error_mgr jerr;
SSIZE_T size = -1;
- char* decomp_data = NULL;
+ BYTE* decomp_data = NULL;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
@@ -734,8 +731,8 @@ void* winpr_convert_to_webp(const void* data, size_t size, UINT32 width, UINT32
#endif
}
-SSIZE_T winpr_convert_from_webp(const char* comp_data, size_t comp_data_bytes, UINT32* width,
- UINT32* height, UINT32* bpp, char** ppdecomp_data)
+SSIZE_T winpr_convert_from_webp(const BYTE* comp_data, size_t comp_data_bytes, UINT32* width,
+ UINT32* height, UINT32* bpp, BYTE** ppdecomp_data)
{
WINPR_ASSERT(comp_data || (comp_data_bytes == 0));
WINPR_ASSERT(width);
@@ -751,13 +748,20 @@ SSIZE_T winpr_convert_from_webp(const char* comp_data, size_t comp_data_bytes, U
return -1;
#else
- uint8_t* dst = WebPDecodeBGRA(comp_data, comp_data_bytes, width, height);
- if (!dst)
+ int w = 0;
+ int h = 0;
+ uint8_t* dst = WebPDecodeBGRA(comp_data, comp_data_bytes, &w, &h);
+ if (!dst || (w < 0) || (h < 0))
+ {
+ free(dst);
return -1;
+ }
+ *width = w;
+ *height = h;
*bpp = 32;
*ppdecomp_data = dst;
- return (*width) * (*height) * 4;
+ return 4ll * w * h;
#endif
}
@@ -1006,8 +1010,8 @@ void* winpr_convert_to_png(const void* data, size_t size, UINT32 width, UINT32 h
#endif
}
-SSIZE_T winpr_convert_from_png(const char* comp_data, size_t comp_data_bytes, UINT32* width,
- UINT32* height, UINT32* bpp, char** ppdecomp_data)
+SSIZE_T winpr_convert_from_png(const BYTE* comp_data, size_t comp_data_bytes, UINT32* width,
+ UINT32* height, UINT32* bpp, BYTE** ppdecomp_data)
{
#if defined(WINPR_UTILS_IMAGE_PNG)
size_t len = 0;
diff --git a/winpr/libwinpr/utils/test/TestStream.c b/winpr/libwinpr/utils/test/TestStream.c
index 00130ae..f86996e 100644
--- a/winpr/libwinpr/utils/test/TestStream.c
+++ b/winpr/libwinpr/utils/test/TestStream.c
@@ -124,7 +124,13 @@ static BOOL TestStream_Static(void)
if (v != 2)
return FALSE;
+ // Intentional warning as the stream is not allocated.
+ // Still, Stream_Free should not release such memory, therefore this statement
+ // is required to test that.
+ WINPR_PRAGMA_DIAG_PUSH
+ WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
Stream_Free(s, TRUE);
+ WINPR_PRAGMA_DIAG_POP
return TRUE;
}