Coverage Report

Created: 2026-10-15 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/channels/rdpgfx/rdpgfx_common.c
Line
Count
Source
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Graphics Pipeline Extension
4
 *
5
 * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2015 Thincast Technologies GmbH
7
 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 *     http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21
22
#include <freerdp/config.h>
23
24
#include <winpr/crt.h>
25
#include <winpr/assert.h>
26
#include <winpr/stream.h>
27
28
#include "rdpgfx_common.h"
29
30
/**
31
 * Function description
32
 *
33
 * @return 0 on success, otherwise a Win32 error code
34
 */
35
UINT rdpgfx_read_header(wLog* log, wStream* s, RDPGFX_HEADER* header, size_t* pPacketLength)
36
293k
{
37
293k
  WINPR_ASSERT(s);
38
293k
  WINPR_ASSERT(header);
39
40
293k
  if (pPacketLength)
41
293k
    *pPacketLength = 0;
42
43
293k
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
44
271
    return ERROR_INVALID_DATA;
45
46
292k
  Stream_Read_UINT16(s, header->cmdId);     /* cmdId (2 bytes) */
47
292k
  Stream_Read_UINT16(s, header->flags);     /* flags (2 bytes) */
48
292k
  Stream_Read_UINT32(s, header->pduLength); /* pduLength (4 bytes) */
49
50
292k
  if (header->pduLength < 8)
51
85
  {
52
85
    WLog_Print(log, WLOG_ERROR, "header->pduLength %u less than 8!", header->pduLength);
53
85
    return ERROR_INVALID_DATA;
54
85
  }
55
56
292k
  const size_t size = (header->pduLength - 8ull);
57
292k
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, size))
58
548
    return ERROR_INVALID_DATA;
59
292k
  if (pPacketLength)
60
292k
    *pPacketLength = size;
61
62
292k
  return CHANNEL_RC_OK;
63
292k
}
64
65
/**
66
 * Function description
67
 *
68
 * @return 0 on success, otherwise a Win32 error code
69
 */
70
UINT rdpgfx_write_header(wStream* s, const RDPGFX_HEADER* header)
71
58.1k
{
72
58.1k
  WINPR_ASSERT(s);
73
58.1k
  WINPR_ASSERT(header);
74
75
58.1k
  if (!Stream_EnsureRemainingCapacity(s, 8))
76
0
    return CHANNEL_RC_NO_MEMORY;
77
58.1k
  Stream_Write_UINT16(s, header->cmdId);     /* cmdId (2 bytes) */
78
58.1k
  Stream_Write_UINT16(s, header->flags);     /* flags (2 bytes) */
79
58.1k
  Stream_Write_UINT32(s, header->pduLength); /* pduLength (4 bytes) */
80
58.1k
  return CHANNEL_RC_OK;
81
58.1k
}
82
83
/**
84
 * Function description
85
 *
86
 * @return 0 on success, otherwise a Win32 error code
87
 */
88
UINT rdpgfx_read_point16(wLog* log, wStream* s, RDPGFX_POINT16* pt16)
89
1.07M
{
90
1.07M
  WINPR_ASSERT(s);
91
1.07M
  WINPR_ASSERT(pt16);
92
93
1.07M
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
94
0
    return ERROR_INVALID_DATA;
95
96
1.07M
  Stream_Read_UINT16(s, pt16->x); /* x (2 bytes) */
97
1.07M
  Stream_Read_UINT16(s, pt16->y); /* y (2 bytes) */
98
1.07M
  return CHANNEL_RC_OK;
99
1.07M
}
100
101
/**
102
 * Function description
103
 *
104
 * @return 0 on success, otherwise a Win32 error code
105
 */
106
UINT rdpgfx_write_point16(wStream* s, const RDPGFX_POINT16* point16)
107
0
{
108
0
  WINPR_ASSERT(s);
109
0
  WINPR_ASSERT(point16);
110
111
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
112
0
    return CHANNEL_RC_NO_MEMORY;
113
114
0
  Stream_Write_UINT16(s, point16->x); /* x (2 bytes) */
115
0
  Stream_Write_UINT16(s, point16->y); /* y (2 bytes) */
116
0
  return CHANNEL_RC_OK;
117
0
}
118
119
/**
120
 * Function description
121
 *
122
 * @return 0 on success, otherwise a Win32 error code
123
 */
124
UINT rdpgfx_read_rect16(wLog* log, wStream* s, RECTANGLE_16* rect16)
125
3.40k
{
126
3.40k
  WINPR_ASSERT(s);
127
3.40k
  WINPR_ASSERT(rect16);
128
129
3.40k
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
130
0
    return ERROR_INVALID_DATA;
131
132
3.40k
  Stream_Read_UINT16(s, rect16->left);   /* left (2 bytes) */
133
3.40k
  Stream_Read_UINT16(s, rect16->top);    /* top (2 bytes) */
134
3.40k
  Stream_Read_UINT16(s, rect16->right);  /* right (2 bytes) */
135
3.40k
  Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
136
3.40k
  if (rect16->left >= rect16->right)
137
65
  {
138
65
    WLog_Print(log, WLOG_ERROR, "Invalid RECTANGLE_16: left(%" PRIu16 ") > right(%" PRIu16 ")",
139
65
               rect16->left, rect16->right);
140
65
    return ERROR_INVALID_DATA;
141
65
  }
142
3.33k
  if (rect16->top >= rect16->bottom)
143
26
  {
144
26
    WLog_Print(log, WLOG_ERROR, "Invalid RECTANGLE_16: top(%" PRIu16 ") > bottom(%" PRIu16 ")",
145
26
               rect16->top, rect16->bottom);
146
26
    return ERROR_INVALID_DATA;
147
26
  }
148
3.31k
  return CHANNEL_RC_OK;
149
3.33k
}
150
151
/**
152
 * Function description
153
 *
154
 * @return 0 on success, otherwise a Win32 error code
155
 */
156
UINT rdpgfx_write_rect16(wStream* s, const RECTANGLE_16* rect16)
157
0
{
158
0
  WINPR_ASSERT(s);
159
0
  WINPR_ASSERT(rect16);
160
161
0
  if (!Stream_EnsureRemainingCapacity(s, 8))
162
0
    return CHANNEL_RC_NO_MEMORY;
163
164
0
  Stream_Write_UINT16(s, rect16->left);   /* left (2 bytes) */
165
0
  Stream_Write_UINT16(s, rect16->top);    /* top (2 bytes) */
166
0
  Stream_Write_UINT16(s, rect16->right);  /* right (2 bytes) */
167
0
  Stream_Write_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
168
0
  return CHANNEL_RC_OK;
169
0
}
170
171
/**
172
 * Function description
173
 *
174
 * @return 0 on success, otherwise a Win32 error code
175
 */
176
UINT rdpgfx_read_color32(wLog* log, wStream* s, RDPGFX_COLOR32* color32)
177
34.7k
{
178
34.7k
  WINPR_ASSERT(s);
179
34.7k
  WINPR_ASSERT(color32);
180
181
34.7k
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
182
0
    return ERROR_INVALID_DATA;
183
184
34.7k
  Stream_Read_UINT8(s, color32->B);  /* B (1 byte) */
185
34.7k
  Stream_Read_UINT8(s, color32->G);  /* G (1 byte) */
186
34.7k
  Stream_Read_UINT8(s, color32->R);  /* R (1 byte) */
187
34.7k
  Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */
188
34.7k
  return CHANNEL_RC_OK;
189
34.7k
}
190
191
/**
192
 * Function description
193
 *
194
 * @return 0 on success, otherwise a Win32 error code
195
 */
196
UINT rdpgfx_write_color32(wStream* s, const RDPGFX_COLOR32* color32)
197
0
{
198
0
  WINPR_ASSERT(s);
199
0
  WINPR_ASSERT(color32);
200
201
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
202
0
    return CHANNEL_RC_NO_MEMORY;
203
204
0
  Stream_Write_UINT8(s, color32->B);  /* B (1 byte) */
205
0
  Stream_Write_UINT8(s, color32->G);  /* G (1 byte) */
206
0
  Stream_Write_UINT8(s, color32->R);  /* R (1 byte) */
207
0
  Stream_Write_UINT8(s, color32->XA); /* XA (1 byte) */
208
0
  return CHANNEL_RC_OK;
209
0
}