<commit_before>/**
 * FreeRDP: A Remote Desktop Protocol Implementation
 * Virtual Channels
 *
 * Copyright 2011 <NAME>
 * Copyright 2015 Copyright 2015 Thincast Technologies GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <freerdp/config.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/wtsapi.h>

#include <freerdp/freerdp.h>
#include <freerdp/constants.h>

#include <freerdp/log.h>
#include <freerdp/svc.h>
#include <freerdp/peer.h>
#include <freerdp/addin.h>

#include <freerdp/client/channels.h>
#include <freerdp/client/drdynvc.h>
#include <freerdp/channels/channels.h>

#include "rdp.h"
#include "client.h"
#include "server.h"
#include "channels.h"

#define TAG FREERDP_TAG("core.channels")

BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channelId, const BYTE* data, size_t size)
{
	DWORD i;
	size_t left;
	UINT32 flags;
	size_t chunkSize;
	rdpMcs* mcs = rdp->mcs;
	const rdpMcsChannel* channel = NULL;

	for (i = 0; i < mcs->channelCount; i++)
	{
		const rdpMcsChannel* cur = &mcs->channels[i];
		if (cur->ChannelId == channelId)
		{
			channel = cur;
			break;
		}
	}

	if (!channel)
	{
		WLog_ERR(TAG, "freerdp_channel_send: unknown channelId %" PRIu16 "", channelId);
		return FALSE;
	}

	flags = CHANNEL_FLAG_FIRST;
	left = size;

	while (left > 0)
	{
		if (left > rdp->settings->VirtualChannelChunkSize)
		{
			chunkSize = rdp->settings->VirtualChannelChunkSize;
		}
		else
		{
			chunkSize = left;
			flags |= CHANNEL_FLAG_LAST;
		}

		if (!rdp->settings->ServerMode && (channel->options & CHANNEL_OPTION_SHOW_PROTOCOL))
		{
			flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
		}

		if (!freerdp_channel_send_packet(rdp, channelId, size, flags, data, chunkSize))
			return FALSE;

		data += chunkSize;
		left -= chunkSize;
		flags = 0;
	}

	return TRUE;
}

BOOL freerdp_channel_process(freerdp* instance, wStream* s, UINT16 channelId, size_t packetLength)
{
	BOOL rc = FALSE;
	UINT32 length;
	UINT32 flags;
	size_t chunkLength;

	if (packetLength < 8)
	{
		WLog_ERR(TAG, "Header length %" PRIdz " bytes promised, none available", packetLength);
		return FALSE;
	}
	packetLength -= 8;

	if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
		return FALSE;

	/* [MS-RDPBCGR] 3.1.5.2.2 Processing of Virtual Channel PDU
	 * chunked data. Length is the total size of the combined data,
	 * chunkLength is the actual data received.
	 * check chunkLength against packetLength, which is the TPKT header size.
	 */
	Stream_Read_UINT32(s, length);
	Stream_Read_UINT32(s, flags);
	chunkLength = Stream_GetRemainingLength(s);
	if (packetLength != chunkLength)
	{
		WLog_ERR(TAG, "Header length %" PRIdz " != actual length %" PRIdz, packetLength,
		         chunkLength);
		return FALSE;
	}
	if (!Stream_CheckAndLogRequiredLength(TAG, s, length))
	{
		WLog_ERR(TAG, "Expected %" PRIu32 " bytes, but have %" PRIdz, length, chunkLength);
		return FALSE;
	}
	IFCALLRET(instance->ReceiveChannelData, rc, instance, channelId, Stream_Pointer(s), chunkLength,
	          flags, length);
	if (!rc)
	{
		WLog_WARN(TAG, "ReceiveChannelData returned %d", rc);<commit_msg>Fixed #7821: Revert length check broken by #7796<commit_after>/**
 * FreeRDP: A Remote Desktop Protocol Implementation
 * Virtual Channels
 *
 * Copyright 2011 <NAME>
 * Copyright 2015 Copyright 2015 Thincast Technologies GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <freerdp/config.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/wtsapi.h>

#include <freerdp/freerdp.h>
#include <freerdp/constants.h>

#include <freerdp/log.h>
#include <freerdp/svc.h>
#include <freerdp/peer.h>
#include <freerdp/addin.h>

#include <freerdp/client/channels.h>
#include <freerdp/client/drdynvc.h>
#include <freerdp/channels/channels.h>

#include "rdp.h"
#include "client.h"
#include "server.h"
#include "channels.h"

#define TAG FREERDP_TAG("core.channels")

BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channelId, const BYTE* data, size_t size)
{
	DWORD i;
	size_t left;
	UINT32 flags;
	size_t chunkSize;
	rdpMcs* mcs = rdp->mcs;
	const rdpMcsChannel* channel = NULL;

	for (i = 0; i < mcs->channelCount; i++)
	{
		const rdpMcsChannel* cur = &mcs->channels[i];
		if (cur->ChannelId == channelId)
		{
			channel = cur;
			break;
		}
	}

	if (!channel)
	{
		WLog_ERR(TAG, "freerdp_channel_send: unknown channelId %" PRIu16 "", channelId);
		return FALSE;
	}

	flags = CHANNEL_FLAG_FIRST;
	left = size;

	while (left > 0)
	{
		if (left > rdp->settings->VirtualChannelChunkSize)
		{
			chunkSize = rdp->settings->VirtualChannelChunkSize;
		}
		else
		{
			chunkSize = left;
			flags |= CHANNEL_FLAG_LAST;
		}

		if (!rdp->settings->ServerMode && (channel->options & CHANNEL_OPTION_SHOW_PROTOCOL))
		{
			flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
		}

		if (!freerdp_channel_send_packet(rdp, channelId, size, flags, data, chunkSize))
			return FALSE;

		data += chunkSize;
		left -= chunkSize;
		flags = 0;
	}

	return TRUE;
}

BOOL freerdp_channel_process(freerdp* instance, wStream* s, UINT16 channelId, size_t packetLength)
{
	BOOL rc = FALSE;
	UINT32 length;
	UINT32 flags;
	size_t chunkLength;

	if (packetLength < 8)
	{
		WLog_ERR(TAG, "Header length %" PRIdz " bytes promised, none available", packetLength);
		return FALSE;
	}
	packetLength -= 8;

	if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
		return FALSE;

	/* [MS-RDPBCGR] 3.1.5.2.2 Processing of Virtual Channel PDU
	 * chunked data. Length is the total size of the combined data,
	 * chunkLength is the actual data received.
	 * check chunkLength against packetLength, which is the TPKT header size.
	 */
	Stream_Read_UINT32(s, length);
	Stream_Read_UINT32(s, flags);
	chunkLength = Stream_GetRemainingLength(s);
	if (packetLength != chunkLength)
	{
		WLog_ERR(TAG, "Header length %" PRIdz " != actual length %" PRIdz, packetLength,
		         chunkLength);
		return FALSE;
	}
	if (length < chunkLength)
	{
		WLog_ERR(TAG, "Expected %" PRIu32 " bytes, but have %" PRIdz, length, chunkLength);
		return FALSE;
	}
	IFCALLRET(instance->ReceiveChannelData, rc, instance, channelId, Stream_Pointer(s), chunkLength,
	          flags, length);
	if (!rc)
	{
		WLog_WARN(TAG, "ReceiveChannelData returned %d", rc);
{'fraction_non_alphanumeric': 0.11871584699453552, 'fraction_numerical': 0.013387978142076503, 'mean_word_length': 4.199573863636363, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4090747', 'n_tokens_mistral': 2765, 'n_tokens_neox': 2561, 'n_words': 715}