clipboard: fail a size request for an entry that has no size

The descriptor now carries FD_FILESIZE only when the size was actually read,
which leaves both size fields at zero for an entry where it was not. The
non-stream FILECONTENTS_SIZE handler passed those fields straight back, so a
receiver asking about such an entry would be told it is empty and would write a
zero-length file without any error. The previous code returned whatever
GetFileSize() had left behind, which for a failure is INVALID_FILE_SIZE -- also
wrong, but wrong loudly.

Answer only when the descriptor has a size, and fail the request otherwise. The
receiver then fails the paste instead of completing it with an empty file, which
is the same class of outcome the old code produced for that entry.

The IStream_Stat path is unchanged; it already answers from the stream.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab
This commit is contained in:
rustdesk
2026-09-16 13:02:04 +08:00
parent f4853a1e41
commit 33f59beebb

View File

@@ -3539,15 +3539,24 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
{
if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE)
{
FILEDESCRIPTORW *fd;
if (clipboard->nFiles <= fileContentsRequest->listIndex)
{
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
*((UINT32 *)&pData[0]) =
clipboard->fileDescriptor[fileContentsRequest->listIndex]->nFileSizeLow;
*((UINT32 *)&pData[4]) =
clipboard->fileDescriptor[fileContentsRequest->listIndex]->nFileSizeHigh;
fd = clipboard->fileDescriptor[fileContentsRequest->listIndex];
// The size fields only mean anything when FD_FILESIZE says so. Answering with
// them regardless would describe an entry whose size could not be read as empty.
if ((fd->dwFlags & FD_FILESIZE) == 0)
{
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
*((UINT32 *)&pData[0]) = fd->nFileSizeLow;
*((UINT32 *)&pData[4]) = fd->nFileSizeHigh;
uSize = cbRequested;
}
else if (fileContentsRequest->dwFlags == FILECONTENTS_RANGE)