From f695413ee785a4ead9f1434295005e03589bd87e Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 4 Jul 2026 15:47:53 +0800 Subject: [PATCH] fix review --- libs/clipboard/src/windows/wf_cliprdr.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libs/clipboard/src/windows/wf_cliprdr.c b/libs/clipboard/src/windows/wf_cliprdr.c index d96ac5ced..1d85387cc 100644 --- a/libs/clipboard/src/windows/wf_cliprdr.c +++ b/libs/clipboard/src/windows/wf_cliprdr.c @@ -299,6 +299,9 @@ struct wf_clipboard // the request is sent and read when its response arrives, so no lock is needed for // it. Used to reject a peer response that claims to return more than requested. ULONG req_f_size_requested; + // Stream ID of the most recent file-contents request. Responses for another stream + // are ignored so they cannot satisfy the shared single-slot rendezvous. + UINT32 req_f_stream_id_expected; // Guards the ownership hand-off of the req_fdata/req_fsize buffer between the // CLIPRDR channel thread (wf_cliprdr_server_file_contents_response, which frees any // stale buffer and publishes the new one) and the explorer-thread consumers @@ -1863,7 +1866,7 @@ UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 connID, co ULONG nreq) { UINT rc; - CLIPRDR_FILE_CONTENTS_REQUEST fileContentsRequest; + CLIPRDR_FILE_CONTENTS_REQUEST fileContentsRequest = { 0 }; if (!clipboard || !clipboard->context || !clipboard->context->ClientFileContentsRequest) return ERROR_INTERNAL_ERROR; @@ -1884,6 +1887,7 @@ UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 connID, co // But it is OK, because it is only used to check if the stream is the same in // `wf_cliprdr_server_file_contents_request()` function. fileContentsRequest.streamId = (UINT32)(ULONG_PTR)streamid; + clipboard->req_f_stream_id_expected = fileContentsRequest.streamId; fileContentsRequest.listIndex = index; fileContentsRequest.dwFlags = flag; fileContentsRequest.nPositionLow = positionlow; @@ -3374,6 +3378,12 @@ wf_cliprdr_server_file_contents_response(CliprdrClientContext *context, rc = ERROR_INTERNAL_ERROR; break; } + + // A response for another stream does not belong to the outstanding request. + // Ignore it without touching the shared response slot or waking its waiter. + if (fileContentsResponse->streamId != clipboard->req_f_stream_id_expected) + return CHANNEL_RC_OK; + // Serialize req_fdata / req_fsize access with the explorer-thread consumers // (CliprdrStream_Read / _New) via req_f_mutex. Held only across the buffer // manipulation below (never across a blocking wait), and released exactly once