Coverage Report

Created: 2026-10-15 06:30

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
0
{
37
0
  WINPR_ASSERT(s);
38
0
  WINPR_ASSERT(header);
39
40
0
  if (pPacketLength)
41
0
    *pPacketLength = 0;
42
43
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
44
0
    return ERROR_INVALID_DATA;
45
46
0
  Stream_Read_UINT16(s, header->cmdId);     /* cmdId (2 bytes) */
47
0
  Stream_Read_UINT16(s, header->flags);     /* flags (2 bytes) */
48
0
  Stream_Read_UINT32(s, header->pduLength); /* pduLength (4 bytes) */
49
50
0
  if (header->pduLength < 8)
51
0
  {
52
0
    WLog_Print(log, WLOG_ERROR, "header->pduLength %u less than 8!", header->pduLength);
53
0
    return ERROR_INVALID_DATA;
54
0
  }
55
56
0
  const size_t size = (header->pduLength - 8ull);
57
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, size))
58
0
    return ERROR_INVALID_DATA;
59
0
  if (pPacketLength)
60
0
    *pPacketLength = size;
61
62
0
  return CHANNEL_RC_OK;
63
0
}
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
0
{
72
0
  WINPR_ASSERT(s);
73
0
  WINPR_ASSERT(header);
74
75
0
  if (!Stream_EnsureRemainingCapacity(s, 8))
76
0
    return CHANNEL_RC_NO_MEMORY;
77
0
  Stream_Write_UINT16(s, header->cmdId);     /* cmdId (2 bytes) */
78
0
  Stream_Write_UINT16(s, header->flags);     /* flags (2 bytes) */
79
0
  Stream_Write_UINT32(s, header->pduLength); /* pduLength (4 bytes) */
80
0
  return CHANNEL_RC_OK;
81
0
}
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
0
{
90
0
  WINPR_ASSERT(s);
91
0
  WINPR_ASSERT(pt16);
92
93
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
94
0
    return ERROR_INVALID_DATA;
95
96
0
  Stream_Read_UINT16(s, pt16->x); /* x (2 bytes) */
97
0
  Stream_Read_UINT16(s, pt16->y); /* y (2 bytes) */
98
0
  return CHANNEL_RC_OK;
99
0
}
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
0
{
126
0
  WINPR_ASSERT(s);
127
0
  WINPR_ASSERT(rect16);
128
129
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
130
0
    return ERROR_INVALID_DATA;
131
132
0
  Stream_Read_UINT16(s, rect16->left);   /* left (2 bytes) */
133
0
  Stream_Read_UINT16(s, rect16->top);    /* top (2 bytes) */
134
0
  Stream_Read_UINT16(s, rect16->right);  /* right (2 bytes) */
135
0
  Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
136
0
  if (rect16->left >= rect16->right)
137
0
  {
138
0
    WLog_Print(log, WLOG_ERROR, "Invalid RECTANGLE_16: left(%" PRIu16 ") > right(%" PRIu16 ")",
139
0
               rect16->left, rect16->right);
140
0
    return ERROR_INVALID_DATA;
141
0
  }
142
0
  if (rect16->top >= rect16->bottom)
143
0
  {
144
0
    WLog_Print(log, WLOG_ERROR, "Invalid RECTANGLE_16: top(%" PRIu16 ") > bottom(%" PRIu16 ")",
145
0
               rect16->top, rect16->bottom);
146
0
    return ERROR_INVALID_DATA;
147
0
  }
148
0
  return CHANNEL_RC_OK;
149
0
}
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
0
{
178
0
  WINPR_ASSERT(s);
179
0
  WINPR_ASSERT(color32);
180
181
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
182
0
    return ERROR_INVALID_DATA;
183
184
0
  Stream_Read_UINT8(s, color32->B);  /* B (1 byte) */
185
0
  Stream_Read_UINT8(s, color32->G);  /* G (1 byte) */
186
0
  Stream_Read_UINT8(s, color32->R);  /* R (1 byte) */
187
0
  Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */
188
0
  return CHANNEL_RC_OK;
189
0
}
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
}