diff --git a/channels/client/addin.c b/channels/client/addin.c index c3a6aab42..012964fc5 100644 --- a/channels/client/addin.c +++ b/channels/client/addin.c @@ -596,6 +596,19 @@ static void free_msg(void* obj) } } +static void channel_client_handler_free(msg_proc_internals* internals) +{ + if (!internals) + return; + + if (internals->thread) + CloseHandle(internals->thread); + MessageQueue_Free(internals->queue); + Stream_Free(internals->data_in, TRUE); + free(internals->channel_name); + free(internals); +} + /* Create message queue and thread or not, depending on settings */ void* channel_client_create_handler(rdpContext* ctx, LPVOID userdata, MsgHandler msg_handler, const char* channel_name) @@ -604,11 +617,16 @@ void* channel_client_create_handler(rdpContext* ctx, LPVOID userdata, MsgHandler if (!internals) { WLog_ERR(TAG, "calloc failed!"); - return 0; + return NULL; } internals->msg_handler = msg_handler; internals->userdata = userdata; - internals->channel_name = _strdup(channel_name); + if (channel_name) + { + internals->channel_name = _strdup(channel_name); + if (!internals->channel_name) + goto fail; + } WINPR_ASSERT(ctx); WINPR_ASSERT(ctx->settings); internals->ctx = ctx; @@ -621,18 +639,21 @@ void* channel_client_create_handler(rdpContext* ctx, LPVOID userdata, MsgHandler if (!internals->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); - return 0; + goto fail; } if (!(internals->thread = CreateThread(NULL, 0, channel_client_thread_proc, (void*)internals, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); - MessageQueue_Free(internals->queue); - internals->queue = NULL; + goto fail; } } return internals; + +fail: + channel_client_handler_free(internals); + return NULL; } /* post a message in the queue or directly call the processing handler */ UINT channel_client_post_message(void* MsgsHandle, LPVOID pData, UINT32 dataLength, @@ -655,9 +676,12 @@ UINT channel_client_post_message(void* MsgsHandle, LPVOID pData, UINT32 dataLeng if (dataFlags & CHANNEL_FLAG_FIRST) { if (internals->data_in) - Stream_Free(internals->data_in, TRUE); - - internals->data_in = Stream_New(NULL, totalLength); + { + if (!Stream_EnsureCapacity(internals->data_in, totalLength)) + return CHANNEL_RC_NO_MEMORY; + } + else + internals->data_in = Stream_New(NULL, totalLength); } if (!(data_in = internals->data_in)) @@ -737,12 +761,8 @@ UINT channel_client_quit_handler(void* MsgsHandle) return rc; } } - MessageQueue_Free(internals->queue); - CloseHandle(internals->thread); } - Stream_Free(internals->data_in, TRUE); - free(internals->channel_name); - free(internals); + channel_client_handler_free(internals); return CHANNEL_RC_OK; } diff --git a/channels/cliprdr/client/cliprdr_format.c b/channels/cliprdr/client/cliprdr_format.c index d5ec1a11d..8b13af453 100644 --- a/channels/cliprdr/client/cliprdr_format.c +++ b/channels/cliprdr/client/cliprdr_format.c @@ -47,7 +47,7 @@ CLIPRDR_FORMAT_LIST cliprdr_filter_format_list(const CLIPRDR_FORMAT_LIST* list, CLIPRDR_FORMAT_LIST filtered = { 0 }; filtered.common.msgType = CB_FORMAT_LIST; filtered.numFormats = list->numFormats; - filtered.formats = calloc(filtered.numFormats, sizeof(CLIPRDR_FORMAT_LIST)); + filtered.formats = calloc(filtered.numFormats, sizeof(CLIPRDR_FORMAT)); size_t wpos = 0; if ((mask & checkMask) == checkMask) diff --git a/channels/disp/client/disp_main.c b/channels/disp/client/disp_main.c index b06ebf9e8..e1c1e85d5 100644 --- a/channels/disp/client/disp_main.c +++ b/channels/disp/client/disp_main.c @@ -283,7 +283,7 @@ static UINT disp_plugin_initialize(GENERIC_DYNVC_PLUGIN* base, rdpContext* rcont disp->MaxMonitorAreaFactorA = 8192; disp->MaxMonitorAreaFactorB = 8192; - context = (DispClientContext*)calloc(1, sizeof(*disp)); + context = (DispClientContext*)calloc(1, sizeof(DispClientContext)); if (!context) { WLog_Print(base->log, WLOG_ERROR, "unable to allocate DispClientContext"); diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 8887cfb04..e117a57fd 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -103,7 +103,12 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, *ppListener = (IWTSListener*)listener; if (!HashTable_Insert(dvcman->listeners, listener->channel_name, listener)) + { + dvcman_wtslistener_free(listener); return ERROR_INTERNAL_ERROR; + } + + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert takes ownership of listener return CHANNEL_RC_OK; } @@ -135,7 +140,7 @@ static UINT dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const ch DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*)pEntryPoints)->dvcman; WINPR_ASSERT(dvcman); - if (!ArrayList_Append(dvcman->plugin_names, _strdup(name))) + if (!ArrayList_Append(dvcman->plugin_names, name)) return ERROR_INTERNAL_ERROR; if (!ArrayList_Append(dvcman->plugins, pPlugin)) return ERROR_INTERNAL_ERROR; @@ -326,6 +331,7 @@ static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) if (!dvcman->plugin_names) goto fail; obj = ArrayList_Object(dvcman->plugin_names); + obj->fnObjectNew = _strdup; obj->fnObjectFree = free; dvcman->plugins = ArrayList_New(TRUE); diff --git a/channels/geometry/client/geometry_main.c b/channels/geometry/client/geometry_main.c index 0a179ee23..04e3254c2 100644 --- a/channels/geometry/client/geometry_main.c +++ b/channels/geometry/client/geometry_main.c @@ -261,7 +261,10 @@ static UINT geometry_recv_pdu(GENERIC_CHANNEL_CALLBACK* callback, wStream* s) Stream_Read_UINT32(s, cbGeometryBuffer); if (!Stream_CheckAndLogRequiredLength(TAG, s, cbGeometryBuffer)) + { + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert ownership mappedGeometry return ERROR_INVALID_DATA; + } if (cbGeometryBuffer) { diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index cc2e9a04d..63bf184e8 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -3051,6 +3051,7 @@ static UINT rdpdr_server_drive_read_file(RdpdrServerContext* context, void* call } /* Send a request to open the directory. */ + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): rdpdr_server_enqueue_irp owns irp return rdpdr_server_send_device_read_request(context, deviceId, fileId, irp->CompletionId, length, offset); } @@ -3127,6 +3128,7 @@ static UINT rdpdr_server_drive_write_file(RdpdrServerContext* context, void* cal } /* Send a request to open the directory. */ + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): rdpdr_server_enqueue_irp owns irp return rdpdr_server_send_device_write_request(context, deviceId, fileId, irp->CompletionId, buffer, length, offset); } @@ -3200,6 +3202,7 @@ static UINT rdpdr_server_drive_close_file(RdpdrServerContext* context, void* cal } /* Send a request to open the directory. */ + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): rdpdr_server_enqueue_irp owns irp return rdpdr_server_send_device_close_request(context, deviceId, fileId, irp->CompletionId); } @@ -3479,6 +3482,7 @@ static UINT rdpdr_server_drive_rename_file(RdpdrServerContext* context, void* ca } /* Send a request to open the file. */ + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): rdpdr_server_enqueue_irp owns irp return rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName, FILE_READ_DATA | SYNCHRONIZE, FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN); diff --git a/channels/rdpemsc/server/mouse_cursor_main.c b/channels/rdpemsc/server/mouse_cursor_main.c index f95316319..d7d2f789b 100644 --- a/channels/rdpemsc/server/mouse_cursor_main.c +++ b/channels/rdpemsc/server/mouse_cursor_main.c @@ -170,6 +170,7 @@ static BOOL read_cap_set(wStream* s, wArrayList* capsSets) return FALSE; } + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): ArrayList_Append owns capsSet return TRUE; } diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index e2fbad553..04f1f5c6f 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -1561,6 +1561,7 @@ static rdpsndPlugin* allocatePlugin(void) fail: if (rdpsnd) audio_format_free(rdpsnd->fixed_format); + free(rdpsnd); return NULL; } /* rdpsnd is always built-in */ diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c index 956c39380..861e4e2a0 100644 --- a/channels/urbdrc/client/libusb/libusb_udevice.c +++ b/channels/urbdrc/client/libusb/libusb_udevice.c @@ -1347,6 +1347,7 @@ static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, async_transfer_user_data_free(user_data); return -1; } + transfer->user_data = user_data; ep_desc = func_get_ep_desc(pdev->LibusbConfig, pdev->MsConfig, EndpointAddress); diff --git a/channels/urbdrc/client/libusb/libusb_udevman.c b/channels/urbdrc/client/libusb/libusb_udevman.c index 264f30513..b90d67aad 100644 --- a/channels/urbdrc/client/libusb/libusb_udevman.c +++ b/channels/urbdrc/client/libusb/libusb_udevman.c @@ -712,6 +712,7 @@ static BOOL urbdrc_udevman_register_devices(UDEVMAN* udevman, const char* device } } + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): ArrayList_Append owns idpair return CHANNEL_RC_OK; } diff --git a/channels/video/client/video_main.c b/channels/video/client/video_main.c index b41e82c45..a23f54c5f 100644 --- a/channels/video/client/video_main.c +++ b/channels/video/client/video_main.c @@ -923,6 +923,7 @@ static UINT video_VideoData(VideoClientContext* context, const TSMM_VIDEO_DATA* return CHANNEL_RC_NO_MEMORY; } + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): Queue_Enqueue owns frame WLog_DBG(TAG, "scheduling frame in %" PRIu32 " ms", (frame->publishTime - startTime)); } } diff --git a/client/SDL/sdl_freerdp.cpp b/client/SDL/sdl_freerdp.cpp index 2b5749c93..ebb32b941 100644 --- a/client/SDL/sdl_freerdp.cpp +++ b/client/SDL/sdl_freerdp.cpp @@ -655,7 +655,7 @@ static const char* sdl_window_get_title(rdpSettings* settings) windowTitle = freerdp_settings_get_string(settings, FreeRDP_WindowTitle); if (windowTitle) - return _strdup(windowTitle); + return windowTitle; name = freerdp_settings_get_server_name(settings); port = freerdp_settings_get_uint32(settings, FreeRDP_ServerPort); @@ -669,7 +669,8 @@ static const char* sdl_window_get_title(rdpSettings* settings) else sprintf_s(buffer, sizeof(buffer), "%s %s:%" PRIu32, prefix, name, port); - freerdp_settings_set_string(settings, FreeRDP_WindowTitle, buffer); + if (!freerdp_settings_set_string(settings, FreeRDP_WindowTitle, buffer)) + return NULL; return freerdp_settings_get_string(settings, FreeRDP_WindowTitle); } diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index 67e725a10..2eec4d09a 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -178,6 +178,23 @@ static xfCachedData* xf_cached_data_new(BYTE* data, UINT32 data_length) return cached_data; } +static xfCachedData* xf_cached_data_new_copy(BYTE* data, UINT32 data_length) +{ + BYTE* copy = NULL; + if (data_length > 0) + { + copy = malloc(data_length); + if (!copy) + return NULL; + memcpy(copy, data, data_length); + } + + xfCachedData* cache = xf_cached_data_new(copy, data_length); + if (!cache) + free(copy); + return cache; +} + static void xf_clipboard_free_server_formats(xfClipboard* clipboard) { WINPR_ASSERT(clipboard); @@ -1384,6 +1401,7 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, formatId = format->formatId; rawTransfer = FALSE; xfCachedData* cached_data = NULL; + xfCachedData* converted_data = NULL; UINT32 dstFormatId = 0; if (formatId == CF_RAW) @@ -1429,7 +1447,7 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, cached_raw_data ? cached_raw_data->data_length : 0); if (cached_raw_data && cached_raw_data->data_length != 0) - cached_data = convert_data_from_existing_raw_data( + converted_data = cached_data = convert_data_from_existing_raw_data( clipboard, cached_raw_data, srcFormatId, nullTerminated, dstFormatId); } @@ -1439,6 +1457,8 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, { /* Cached clipboard data available. Send it now */ respond->property = xevent->property; + + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc) xf_cliprdr_provide_data(clipboard, respond, cached_data->data, cached_data->data_length); } @@ -1994,7 +2014,6 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context, xfContext* xfc = NULL; xfClipboard* clipboard = NULL; xfCachedData* cached_data = NULL; - BYTE* raw_data = NULL; WINPR_ASSERT(context); WINPR_ASSERT(formatDataResponse); @@ -2153,20 +2172,12 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context, /* We have to copy the original data again, as pSrcData is now owned * by clipboard->system. Memory allocation failure is not fatal here * as this is only a cached value. */ - raw_data = malloc(size); - - if (raw_data) { - xfCachedData* cached_raw_data = NULL; - - CopyMemory(raw_data, data, size); - - cached_raw_data = xf_cached_data_new(raw_data, size); + // clipboard->cachedData owns cached_data + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc + xfCachedData* cached_raw_data = xf_cached_data_new_copy(data, size); if (!cached_raw_data) - { WLog_WARN(TAG, "Failed to allocate cache entry"); - free(raw_data); - } else { if (!HashTable_Insert(clipboard->cachedRawData, (void*)(UINT_PTR)srcFormatId, @@ -2174,16 +2185,12 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context, { WLog_WARN(TAG, "Failed to cache clipboard data"); xf_cached_data_free(cached_raw_data); - xf_cached_data_free(cached_data); } } } - else - { - WLog_WARN(TAG, "failed to allocate %" PRIu32 " bytes for a copy of raw clipboard data", - size); - } + // clipboard->cachedRawData owns cached_raw_data + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc) xf_cliprdr_provide_data(clipboard, clipboard->respond, pDstData, DstSize); { union diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 88d51d6f7..6fb32be97 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -169,7 +169,6 @@ const char* x11_event_string(int event) BOOL xf_event_action_script_init(xfContext* xfc) { wObject* obj = NULL; - char* xevent = NULL; FILE* actionScript = NULL; char buffer[1024] = { 0 }; char command[1024] = { 0 }; @@ -187,6 +186,8 @@ BOOL xf_event_action_script_init(xfContext* xfc) return FALSE; obj = ArrayList_Object(xfc->xevents); + WINPR_ASSERT(obj); + obj->fnObjectNew = _strdup; obj->fnObjectFree = free; ActionScript = freerdp_settings_get_string(settings, FreeRDP_ActionScript); sprintf_s(command, sizeof(command), "%s xevent", ActionScript); @@ -199,9 +200,8 @@ BOOL xf_event_action_script_init(xfContext* xfc) { char* context = NULL; strtok_s(buffer, "\n", &context); - xevent = _strdup(buffer); - if (!xevent || !ArrayList_Append(xfc->xevents, xevent)) + if (!buffer || !ArrayList_Append(xfc->xevents, buffer)) { pclose(actionScript); ArrayList_Free(xfc->xevents); diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index c5e913382..022ca123e 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -82,7 +82,6 @@ static BOOL xf_keyboard_action_script_init(xfContext* xfc) { wObject* obj = NULL; FILE* keyScript = NULL; - char* keyCombination = NULL; char buffer[1024] = { 0 }; char command[1024] = { 0 }; const rdpSettings* settings = NULL; @@ -104,6 +103,8 @@ static BOOL xf_keyboard_action_script_init(xfContext* xfc) return FALSE; obj = ArrayList_Object(xfc->keyCombinations); + WINPR_ASSERT(obj); + obj->fnObjectNew = _strdup; obj->fnObjectFree = free; sprintf_s(command, sizeof(command), "%s key", ActionScript); keyScript = popen(command, "r"); @@ -118,9 +119,8 @@ static BOOL xf_keyboard_action_script_init(xfContext* xfc) { char* context = NULL; strtok_s(buffer, "\n", &context); - keyCombination = _strdup(buffer); - if (!keyCombination || !ArrayList_Append(xfc->keyCombinations, keyCombination)) + if (!buffer || !ArrayList_Append(xfc->keyCombinations, buffer)) { ArrayList_Free(xfc->keyCombinations); xfc->actionScriptExists = FALSE; diff --git a/client/common/client_cliprdr_file.c b/client/common/client_cliprdr_file.c index cc71aaecd..3e108cd73 100644 --- a/client/common/client_cliprdr_file.c +++ b/client/common/client_cliprdr_file.c @@ -559,6 +559,8 @@ static UINT prepare_clip_data_entry_with_id(CliprdrFileContext* file_context) } HashTable_Unlock(file_context->inode_table); + // HashTable_Insert owns clip_data_entry + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc) file_context->current_clip_data_id = clip_data_entry->clip_data_id; return CHANNEL_RC_OK; @@ -936,15 +938,18 @@ static BOOL request_file_range_async(CliprdrFileContext* file_context, CliprdrFu "Failed to send FileContentsRequest for file \"%s\"", fuse_file->filename_with_root); HashTable_Remove(file_context->request_table, (void*)(UINT_PTR)fuse_request->stream_id); - free(fuse_request); return FALSE; } + + // file_context->request_table owns fuse_request + // NOLINTBEGIN(clang-analyzer-unix.Malloc) DEBUG_CLIPRDR( file_context->log, "Requested file range (%zu Bytes at offset %lu) for file \"%s\" with stream id %u", requested_size, offset, fuse_file->filename, fuse_request->stream_id); return TRUE; + // NOLINTEND(clang-analyzer-unix.Malloc) } static void cliprdr_file_fuse_read(fuse_req_t fuse_req, fuse_ino_t fuse_ino, size_t size, @@ -1840,6 +1845,7 @@ static BOOL set_selection_for_clip_data_entry(CliprdrFileContext* file_context, else WLog_Print(file_context->log, WLOG_DEBUG, "Setting selection"); + // NOLINTBEGIN(clang-analyzer-unix.Malloc) HashTable_Insert owns fuse_file for (UINT32 i = 0; i < n_files; ++i) { FILEDESCRIPTORW* file = &files[i]; @@ -1939,6 +1945,7 @@ static BOOL set_selection_for_clip_data_entry(CliprdrFileContext* file_context, return FALSE; } } + // NOLINTEND(clang-analyzer-unix.Malloc) HashTable_Insert owns fuse_file if (clip_data_entry->has_clip_data_id) WLog_Print(file_context->log, WLOG_DEBUG, "Selection set for clipDataId %u", @@ -2516,7 +2523,11 @@ BOOL cliprdr_file_context_update_client_data(CliprdrFileContext* file, const cha { stream = cliprdr_local_stream_new(file, lockId, data, size); rc = HashTable_Insert(file->local_streams, &stream->lockId, stream); + if (!rc) + cliprdr_local_stream_free(stream); } + // HashTable_Insert owns stream + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc) HashTable_Unlock(file->local_streams); return rc; } diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 0da63282c..56bf42031 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -2540,6 +2540,7 @@ static int parse_vmconnect_options(rdpSettings* settings, const COMMAND_LINE_ARG static int parse_size_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_A* arg) { + int status = 0; WINPR_ASSERT(settings); WINPR_ASSERT(arg); @@ -2572,26 +2573,27 @@ static int parse_size_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT { BOOL partial = FALSE; + status = COMMAND_LINE_ERROR; if (strchr(p, 'w')) { if (!freerdp_settings_set_bool(settings, FreeRDP_PercentScreenUseWidth, TRUE)) - return COMMAND_LINE_ERROR; + goto fail; partial = TRUE; } if (strchr(p, 'h')) { if (!freerdp_settings_set_bool(settings, FreeRDP_PercentScreenUseHeight, TRUE)) - return COMMAND_LINE_ERROR; + goto fail; partial = TRUE; } if (!partial) { if (!freerdp_settings_set_bool(settings, FreeRDP_PercentScreenUseWidth, TRUE)) - return COMMAND_LINE_ERROR; + goto fail; if (!freerdp_settings_set_bool(settings, FreeRDP_PercentScreenUseHeight, TRUE)) - return COMMAND_LINE_ERROR; + goto fail; } *p = '\0'; @@ -2600,19 +2602,22 @@ static int parse_size_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT if (!value_to_int(str, &val, 0, 100)) { - free(str); - return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + status = COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + goto fail; } if (!freerdp_settings_set_uint32(settings, FreeRDP_PercentScreen, (UINT32)val)) - return COMMAND_LINE_ERROR; + goto fail; } + + status = 0; } + fail: free(str); } - return 0; + return status; } static int parse_monitors_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_A* arg) @@ -2773,6 +2778,7 @@ static int parse_kbd_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_ rc = COMMAND_LINE_ERROR_MEMORY; else _snprintf(tmp, tlen, "%s,%s", old, now); + free(now); now = tmp; } @@ -5312,7 +5318,7 @@ static void argv_free(int* pargc, char** pargv[]) free(argv); } -static BOOL argv_append(int* pargc, char** pargv[], char* what) +static BOOL argv_append(int* pargc, char** pargv[], const char* what) { WINPR_ASSERT(pargc); WINPR_ASSERT(pargv); @@ -5334,6 +5340,18 @@ static BOOL argv_append(int* pargc, char** pargv[], char* what) return TRUE; } +static BOOL argv_append_dup(int* pargc, char** pargv[], const char* what) +{ + char* copy = NULL; + if (what) + copy = _strdup(what); + + const BOOL rc = argv_append(pargc, pargv, copy); + if (!rc) + free(copy); + return rc; +} + static BOOL args_from_fp(FILE* fp, int* aargc, char** aargv[], const char* file, const char* cmd) { BOOL success = FALSE; @@ -5347,7 +5365,7 @@ static BOOL args_from_fp(FILE* fp, int* aargc, char** aargv[], const char* file, WLog_ERR(TAG, "Failed to read command line options from file '%s'", file); return FALSE; } - if (!argv_append(aargc, aargv, _strdup(cmd))) + if (!argv_append_dup(aargc, aargv, cmd)) goto fail; while (!feof(fp)) { @@ -5380,7 +5398,10 @@ static BOOL args_from_fp(FILE* fp, int* aargc, char** aargv[], const char* file, break; } if (!argv_append(aargc, aargv, line)) + { + free(line); goto fail; + } } success = TRUE; @@ -5425,14 +5446,14 @@ static BOOL args_from_env(const char* name, int* aargc, char** aargv[], const ch goto cleanup; } - if (!argv_append(aargc, aargv, _strdup(cmd))) + if (!argv_append_dup(aargc, aargv, cmd)) goto cleanup; char* context = NULL; char* tok = strtok_s(env, "\n", &context); while (tok) { - if (!argv_append(aargc, aargv, _strdup(tok))) + if (!argv_append_dup(aargc, aargv, tok)) goto cleanup; tok = strtok_s(NULL, "\n", &context); } diff --git a/libfreerdp/cache/persistent.c b/libfreerdp/cache/persistent.c index d1f123214..8499c7eca 100644 --- a/libfreerdp/cache/persistent.c +++ b/libfreerdp/cache/persistent.c @@ -351,7 +351,10 @@ rdpPersistentCache* persistent_cache_new(void) persistent->bmpData = calloc(1, persistent->bmpSize); if (!persistent->bmpData) + { + free(persistent); return NULL; + } return persistent; } diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index b72c34c2f..4b211b865 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -126,7 +126,10 @@ static BOOL allocate_h264_metablock(UINT32 QP, RECTANGLE_16* rectangles, /* [MS-RDPEGFX] 2.2.4.4.2 RDPGFX_AVC420_QUANT_QUALITY */ if (!meta || (QP > UINT8_MAX)) + { + free(rectangles); return FALSE; + } meta->regionRects = rectangles; if (count == 0) diff --git a/libfreerdp/common/assistance.c b/libfreerdp/common/assistance.c index 8aa112af1..fb0cd007e 100644 --- a/libfreerdp/common/assistance.c +++ b/libfreerdp/common/assistance.c @@ -248,6 +248,21 @@ fail: return rc; } +static BOOL append_address_to_list(wArrayList* MachineAddresses, const char* str, size_t len) +{ + char* copy = NULL; + if (len > 0) + copy = strndup(str, len); + if (!copy) + return FALSE; + + const BOOL rc = ArrayList_Append(MachineAddresses, copy); + if (!rc) + free(copy); + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): ArrayList_Append takes ownership of copy + return rc; +} + static BOOL append_address(rdpAssistanceFile* file, const char* host, const char* port) { WINPR_ASSERT(file); @@ -262,7 +277,7 @@ static BOOL append_address(rdpAssistanceFile* file, const char* host, const char return FALSE; } - if (!ArrayList_Append(file->MachineAddresses, _strdup(host))) + if (!append_address_to_list(file->MachineAddresses, host, host ? strlen(host) : 0)) return FALSE; return ArrayList_Append(file->MachinePorts, (void*)(uintptr_t)p); } @@ -664,14 +679,14 @@ static BOOL freerdp_assistance_parse_all_elements_of_l(rdpAssistanceFile* file, if (n && (nlen > 0)) { - if (!ArrayList_Append(file->MachineAddresses, strndup(n, nlen))) + if (!append_address_to_list(file->MachineAddresses, n, nlen)) return FALSE; if (!ArrayList_Append(file->MachinePorts, (void*)(uintptr_t)p)) return FALSE; } if (u && (ulen > 0)) { - if (!ArrayList_Append(file->MachineAddresses, strndup(u, ulen))) + if (!append_address_to_list(file->MachineAddresses, u, ulen)) return FALSE; if (!ArrayList_Append(file->MachinePorts, (void*)(uintptr_t)p)) return FALSE; diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 9478bd975..48f797134 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -1273,6 +1273,9 @@ BOOL freerdp_settings_set_pointer_len_(rdpSettings* settings, FreeRDP_Settings_K free(copy); return FALSE; } + + // freerdp_settings_set_pointer takes ownership of copy + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc) if (lenId < 0) return TRUE; return freerdp_settings_set_uint32(settings, (FreeRDP_Settings_Keys_UInt32)lenId, len); diff --git a/libfreerdp/core/activation.c b/libfreerdp/core/activation.c index 1e3fc8e23..77e91814f 100644 --- a/libfreerdp/core/activation.c +++ b/libfreerdp/core/activation.c @@ -397,11 +397,15 @@ BOOL rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp) wStream* s = rdp_data_pdu_init(rdp); if (!s) + { + free(keyList); return FALSE; + } if (!rdp_write_client_persistent_key_list_pdu(s, &info)) { Stream_Free(s, TRUE); + free(keyList); return FALSE; } diff --git a/libfreerdp/core/credssp_auth.c b/libfreerdp/core/credssp_auth.c index 63500368f..c14dbe158 100644 --- a/libfreerdp/core/credssp_auth.c +++ b/libfreerdp/core/credssp_auth.c @@ -765,22 +765,23 @@ static void auth_get_sspi_module_from_reg(char** sspi_module) return; } - *sspi_module = (LPSTR)malloc(dwSize + sizeof(CHAR)); - if (!(*sspi_module)) + char* module = (LPSTR)calloc(dwSize + sizeof(CHAR), sizeof(char)); + if (!module) { RegCloseKey(hKey); return; } - if (RegQueryValueExA(hKey, "SspiModule", NULL, &dwType, (BYTE*)(*sspi_module), &dwSize) != + if (RegQueryValueExA(hKey, "SspiModule", NULL, &dwType, (BYTE*)module, &dwSize) != ERROR_SUCCESS) { RegCloseKey(hKey); - free(*sspi_module); + free(module); return; } RegCloseKey(hKey); + *sspi_module = module; } static SecurityFunctionTable* auth_resolve_sspi_table(const rdpSettings* settings) diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 4c3b30790..36942fa5e 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -1071,6 +1071,7 @@ BOOL rpc_client_write_call(rdpRpc* rpc, wStream* s, UINT16 opnum) goto fail; } + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): ArrayList_Append takes ownership of clientCall if (request_pdu.opnum == TsProxySetupReceivePipeOpnum) rpc->PipeCallId = request_pdu.header.call_id; diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 093d22040..a46b357d4 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -1088,7 +1088,6 @@ static BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s, logon_info* info) WINPR_UNUSED(rdp); WINPR_ASSERT(info); - rdp_free_logon_info(info); if (!Stream_CheckAndLogRequiredLength(TAG, s, 576)) return FALSE; @@ -1114,7 +1113,6 @@ static BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s, logon_info* info) info->sessionId, info->username, info->domain); return TRUE; fail: - rdp_free_logon_info(info); return FALSE; } @@ -1130,7 +1128,6 @@ static BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s, logon_info* info) WINPR_ASSERT(info); WINPR_UNUSED(rdp); - rdp_free_logon_info(info); if (!Stream_CheckAndLogRequiredLength(TAG, s, logonInfoV2TotalSize)) return FALSE; @@ -1210,7 +1207,6 @@ static BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s, logon_info* info) info->sessionId, info->username, info->domain); return TRUE; fail: - rdp_free_logon_info(info); return FALSE; } @@ -1344,8 +1340,7 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s) if (status && update->SaveSessionInfo) status = update->SaveSessionInfo(context, infoType, &logonInfo); - free(logonInfo.domain); - free(logonInfo.username); + rdp_free_logon_info(&logonInfo); break; case INFO_TYPE_LOGON_LONG: diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index c8ba0c6c5..2c4bf228c 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -1533,13 +1533,12 @@ BOOL freerdp_peer_context_new_ex(freerdp_peer* client, const rdpSettings* settin if (!(context = (rdpContext*)calloc(1, client->ContextSize))) goto fail; - context->log = WLog_Get(TAG); - if (!context->log) - goto fail; - client->context = context; context->peer = client; context->ServerMode = TRUE; + context->log = WLog_Get(TAG); + if (!context->log) + goto fail; if (settings) { diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c index de8cebfc1..816177266 100644 --- a/libfreerdp/core/redirection.c +++ b/libfreerdp/core/redirection.c @@ -124,7 +124,7 @@ static BOOL redirection_copy_array(char*** dst, UINT32* plen, const char** str, if (!str || (len == 0)) return TRUE; - *dst = calloc(len, sizeof(char)); + *dst = calloc(len, sizeof(char*)); if (!*dst) return FALSE; *plen = len; @@ -446,10 +446,9 @@ static BOOL rdp_redirection_read_target_cert_stream(wStream* s, rdpRedirection* WINPR_ASSERT(redirection); - if (!rdp_redirection_read_base64_wchar(LB_TARGET_CERTIFICATE, s, &length, &ptr)) - return FALSE; - - const BOOL rc = rdp_redirection_read_target_cert(&redirection->TargetCertificate, ptr, length); + BOOL rc = FALSE; + if (rdp_redirection_read_base64_wchar(LB_TARGET_CERTIFICATE, s, &length, &ptr)) + rc = rdp_redirection_read_target_cert(&redirection->TargetCertificate, ptr, length); free(ptr); return rc; } diff --git a/libfreerdp/emu/scard/smartcard_emulate.c b/libfreerdp/emu/scard/smartcard_emulate.c index 25e4f1687..ad13b6264 100644 --- a/libfreerdp/emu/scard/smartcard_emulate.c +++ b/libfreerdp/emu/scard/smartcard_emulate.c @@ -307,8 +307,8 @@ static SCardHandle* scard_handle_new(SmartcardEmulationContext* smartcard, SCARD { size_t s = strlen(name); - hdl->szReader.pw = calloc(s + 2, sizeof(CHAR)); - if (!hdl->szReader.pw) + hdl->szReader.pc = calloc(s + 2, sizeof(CHAR)); + if (!hdl->szReader.pc) goto fail; memcpy(hdl->szReader.pv, name, s * sizeof(CHAR)); } @@ -438,6 +438,7 @@ LONG WINAPI Emulate_SCardEstablishContext(SmartcardEmulationContext* smartcard, if (status != SCARD_S_SUCCESS) scard_context_free(ctx); + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert takes ownership of ctx return status; } @@ -2309,6 +2310,8 @@ static LONG insert_data(wHashTable* table, DWORD FreshnessCounter, const void* k item->freshness = FreshnessCounter; item->size = DataLen; memcpy(item->data, Data, DataLen); + + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert takes ownership of item return SCARD_S_SUCCESS; } diff --git a/libfreerdp/emu/scard/smartcard_virtual_gids.c b/libfreerdp/emu/scard/smartcard_virtual_gids.c index 01142c467..178d56123 100644 --- a/libfreerdp/emu/scard/smartcard_virtual_gids.c +++ b/libfreerdp/emu/scard/smartcard_virtual_gids.c @@ -266,6 +266,8 @@ typedef struct vgids_keymap_record vgidsKeymapRecord; #pragma pack(pop) +static void vgids_ef_free(void* ptr); + static vgidsEF* vgids_ef_new(vgidsContext* ctx, USHORT id) { vgidsEF* ef = calloc(1, sizeof(vgidsEF)); @@ -288,7 +290,7 @@ static vgidsEF* vgids_ef_new(vgidsContext* ctx, USHORT id) return ef; create_failed: - free(ef); + vgids_ef_free(ef); return NULL; } @@ -406,7 +408,7 @@ static BOOL vgids_ef_read_do(vgidsEF* ef, UINT16 doID, BYTE** data, DWORD* dataS return FALSE; } -static void vgids_ef_free(void* ptr) +void vgids_ef_free(void* ptr) { vgidsEF* ef = ptr; if (ef) @@ -1562,6 +1564,9 @@ BOOL vgids_init(vgidsContext* ctx, const char* cert, const char* privateKey, con rc = TRUE; init_failed: + // ArrayList_Append in vgids_ef_new takes ownership + // of cardidEF, commonEF, masterEF + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc) free(kxc); free(keymap); free(fsTable); diff --git a/libfreerdp/utils/smartcard_call.c b/libfreerdp/utils/smartcard_call.c index b796d1681..f8d9991b2 100644 --- a/libfreerdp/utils/smartcard_call.c +++ b/libfreerdp/utils/smartcard_call.c @@ -84,6 +84,8 @@ struct s_scard_context_element void (*fn_free)(void*); }; +static void context_free(void* arg); + static LONG smartcard_EstablishContext_Call(scard_call_context* smartcard, wStream* out, SMARTCARD_OPERATION* operation) { @@ -114,15 +116,10 @@ static LONG smartcard_EstablishContext_Call(scard_call_context* smartcard, wStre } } - if (!pContext) - { - WLog_ERR(TAG, "smartcard_context_new failed!"); - return STATUS_NO_MEMORY; - } - if (!HashTable_Insert(smartcard->rgSCardContextList, key, (void*)pContext)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); + context_free(pContext); return STATUS_INTERNAL_ERROR; } } @@ -131,6 +128,7 @@ static LONG smartcard_EstablishContext_Call(scard_call_context* smartcard, wStre return scard_log_status_error(TAG, "SCardEstablishContext", status); } + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert takes ownership of pContext smartcard_scard_context_native_to_redir(&(ret.hContext), hContext); status = smartcard_pack_establish_context_return(out, &ret); @@ -1823,7 +1821,7 @@ LONG smartcard_irp_device_control_call(scard_call_context* smartcard, wStream* o return SCARD_S_SUCCESS; } -static void context_free(void* arg) +void context_free(void* arg) { struct s_scard_context_element* element = arg; if (!arg) diff --git a/libfreerdp/utils/test/TestPodArrays.c b/libfreerdp/utils/test/TestPodArrays.c index 0c178c474..0074fb7a0 100644 --- a/libfreerdp/utils/test/TestPodArrays.c +++ b/libfreerdp/utils/test/TestPodArrays.c @@ -60,68 +60,73 @@ POD_ARRAYS_IMPL(BasicStruct, basicstruct) int TestPodArrays(int argc, char* argv[]) { + int rc = -1; UINT32 i = 0; UINT32 sum = 0; UINT32 foreach_index = 0; - ArrayUINT32 uint32s; + ArrayUINT32 uint32s = { 0 }; UINT32* ptr = NULL; const UINT32* cptr = NULL; - ArrayBasicStruct basicStructs; + ArrayBasicStruct basicStructs = { 0 }; BasicStruct basicStruct = { 1, 2 }; array_uint32_init(&uint32s); + array_basicstruct_init(&basicStructs); + for (i = 0; i < 10; i++) if (!array_uint32_append(&uint32s, i)) - return -1; + goto fail; sum = 0; if (!array_uint32_foreach(&uint32s, cb_compute_sum, &sum)) - return -2; + goto fail; if (sum != 45) - return -3; + goto fail; foreach_index = 0; if (array_uint32_foreach(&uint32s, cb_stop_at_5, &foreach_index)) - return -4; + goto fail; if (foreach_index != 5) - return -5; + goto fail; if (array_uint32_get(&uint32s, 4) != 4) - return -6; + goto fail; array_uint32_set(&uint32s, 4, 5); if (array_uint32_get(&uint32s, 4) != 5) - return -7; + goto fail; ptr = array_uint32_data(&uint32s); if (*ptr != 0) - return -8; + goto fail; cptr = array_uint32_cdata(&uint32s); if (*cptr != 0) - return -9; + goto fail; /* test modifying values of the array during the foreach */ if (!array_uint32_foreach(&uint32s, cb_set_to_1, NULL) || array_uint32_get(&uint32s, 5) != 1) - return -10; + goto fail; /* this one is to test that we can modify the array itself during the foreach and that things * go nicely */ if (!array_uint32_foreach(&uint32s, cb_reset_after_1, &uint32s) || array_uint32_size(&uint32s)) - return -11; - - array_uint32_uninit(&uint32s); + goto fail; /* give a try with an array of BasicStructs */ - array_basicstruct_init(&basicStructs); if (!array_basicstruct_append(&basicStructs, basicStruct)) - return -20; + goto fail; if (!array_basicstruct_foreach(&basicStructs, cb_basic_struct, NULL)) - return -21; + goto fail; + rc = 0; + +fail: + array_uint32_uninit(&uint32s); array_basicstruct_uninit(&basicStructs); - return 0; + + return rc; } diff --git a/server/proxy/channels/pf_channel_drdynvc.c b/server/proxy/channels/pf_channel_drdynvc.c index a16d8763b..9d8cab905 100644 --- a/server/proxy/channels/pf_channel_drdynvc.c +++ b/server/proxy/channels/pf_channel_drdynvc.c @@ -413,6 +413,7 @@ static PfChannelResult DynvcTrackerPeekFn(ChannelStateTracker* tracker, BOOL fir dynChannel->openStatus = CHANNEL_OPENSTATE_WAITING_OPEN_STATUS; + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert owns dynChannel return channelTracker_flushCurrent(tracker, firstPacket, lastPacket, FALSE); } diff --git a/server/proxy/channels/pf_channel_rdpdr.c b/server/proxy/channels/pf_channel_rdpdr.c index 424b4c974..31134878c 100644 --- a/server/proxy/channels/pf_channel_rdpdr.c +++ b/server/proxy/channels/pf_channel_rdpdr.c @@ -1745,7 +1745,10 @@ BOOL pf_channel_rdpdr_client_new(pClientContext* pc) WINPR_ASSERT(obj); obj->fnObjectNew = stream_copy; obj->fnObjectFree = stream_free; - return HashTable_Insert(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME, rdpdr); + if (!HashTable_Insert(pc->interceptContextMap, RDPDR_SVC_CHANNEL_NAME, rdpdr)) + goto fail; + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert takes ownership of rdpdr + return TRUE; fail: pf_channel_rdpdr_client_context_free(&rdpdr->common.base); return FALSE; @@ -1815,7 +1818,11 @@ BOOL pf_channel_rdpdr_server_new(pServerContext* ps) rdpdr->handle = WTSVirtualChannelOpenEx(rdpdr->SessionId, RDPDR_SVC_CHANNEL_NAME, 0); if (rdpdr->handle == 0) goto fail; - return HashTable_Insert(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME, rdpdr); + if (!HashTable_Insert(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME, rdpdr)) + goto fail; + + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert takes ownership of rdpdr + return TRUE; fail: pf_channel_rdpdr_server_context_free(&rdpdr->common.base); return FALSE; diff --git a/winpr/libwinpr/clipboard/synthetic.c b/winpr/libwinpr/clipboard/synthetic.c index 19e051031..545f8dbc2 100644 --- a/winpr/libwinpr/clipboard/synthetic.c +++ b/winpr/libwinpr/clipboard/synthetic.c @@ -343,7 +343,7 @@ static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 form if (SrcSize > 2) { if (SrcSize > INT_MAX) - return NULL; + goto fail; /* Check the BOM (Byte Order Mark) */ if ((pSrcData.cpb[0] == 0xFE) && (pSrcData.cpb[1] == 0xFF)) diff --git a/winpr/libwinpr/ncrypt/test/TestNCryptSmartcard.c b/winpr/libwinpr/ncrypt/test/TestNCryptSmartcard.c index b028fbc87..5126b3b27 100644 --- a/winpr/libwinpr/ncrypt/test/TestNCryptSmartcard.c +++ b/winpr/libwinpr/ncrypt/test/TestNCryptSmartcard.c @@ -46,13 +46,13 @@ static void crypto_print_name(const BYTE* b, DWORD sz) if (!name) goto x509_release; - ret = malloc(1024); + ret = calloc(1024, sizeof(char)); if (!ret) goto bio_release; - ret = X509_NAME_oneline(name, ret, 1024); + char* ret2 = X509_NAME_oneline(name, ret, 1024); - printf("\t%s\n", ret); + printf("\t%s\n", ret2); free(ret); x509_release: diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 1c29173d9..75f7bcca4 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -690,6 +690,7 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD if (!ArrayList_Append(g_NamedPipeServerSockets, baseSocket)) { free(baseSocket->name); + free(baseSocket); goto out; } @@ -714,6 +715,7 @@ HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD #endif } + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): ArrayList_Append takes ownership of baseSocket ArrayList_Unlock(g_NamedPipeServerSockets); return pNamedPipe; out: diff --git a/winpr/libwinpr/pool/work.c b/winpr/libwinpr/pool/work.c index 765e90f3a..e83f41736 100644 --- a/winpr/libwinpr/pool/work.c +++ b/winpr/libwinpr/pool/work.c @@ -149,8 +149,10 @@ VOID winpr_SubmitThreadpoolWork(PTP_WORK pwk) { callbackInstance->Work = pwk; CountdownEvent_AddCount(pool->WorkComplete, 1); - Queue_Enqueue(pool->PendingQueue, callbackInstance); + if (!Queue_Enqueue(pool->PendingQueue, callbackInstance)) + free(callbackInstance); } + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): Queue_Enqueue takes ownership of callbackInstance } BOOL winpr_TrySubmitThreadpoolCallback(PTP_SIMPLE_CALLBACK pfns, PVOID pv, diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 78eac282b..99c1e429a 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -1740,6 +1740,8 @@ static LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, LPCSTR szRe pCard = PCSC_ConnectCardHandle(hContext, *phCard); *pdwActiveProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD)pcsc_dwActiveProtocol); pCard->shared = shared; + + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): ListDictionary_Add takes ownership of pCard PCSC_WaitForCardAccess(hContext, pCard->hSharedContext, shared); } @@ -1978,7 +1980,7 @@ static LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderN pcsc_cchReaderLen++; #endif - tReader = calloc(sizeof(WCHAR), pcsc_cchReaderLen); + tReader = calloc(sizeof(CHAR), pcsc_cchReaderLen + 1); if (!tReader) { @@ -2874,7 +2876,7 @@ static LONG WINAPI PCSC_SCardWriteCacheA(SCARDCONTEXT hContext, UUID* CardIdenti free(id); return SCARD_E_NO_MEMORY; } - data->data = malloc(DataLen); + data->data = calloc(DataLen, 1); if (!data->data) { free(id); @@ -2895,6 +2897,7 @@ static LONG WINAPI PCSC_SCardWriteCacheA(SCARDCONTEXT hContext, UUID* CardIdenti return SCARD_E_NO_MEMORY; } + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert owns data return SCARD_S_SUCCESS; } @@ -2940,6 +2943,7 @@ static LONG WINAPI PCSC_SCardWriteCacheW(SCARDCONTEXT hContext, UUID* CardIdenti return SCARD_E_NO_MEMORY; } + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert owns data return SCARD_S_SUCCESS; } diff --git a/winpr/libwinpr/sspi/Kerberos/kerberos.c b/winpr/libwinpr/sspi/Kerberos/kerberos.c index 04497929d..b7b71f954 100644 --- a/winpr/libwinpr/sspi/Kerberos/kerberos.c +++ b/winpr/libwinpr/sspi/Kerberos/kerberos.c @@ -678,6 +678,8 @@ static BOOL kerberos_rd_tgt_token(const sspi_gss_data* token, char** target, krb fail: free(buf); + if (target) + *target = NULL; return FALSE; }