update: add proper stream checks

This commit is contained in:
Kobi Mizrachi 2019-12-17 11:16:54 +02:00 committed by akallabeth
parent f92e941129
commit 200f50c1f6

View File

@ -2016,130 +2016,185 @@ static BOOL update_send_set_keyboard_ime_status(rdpContext* context, UINT16 imeI
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS, rdp->mcs->userId);
}
static UINT16 update_calculate_new_or_existing_window(const WINDOW_ORDER_INFO* orderInfo,
const WINDOW_STATE_ORDER* stateOrder)
{
UINT16 orderSize = 11;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) != 0)
orderSize += 4;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE) != 0)
orderSize += 8;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW) != 0)
orderSize += 1;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) != 0)
orderSize += 2 + stateOrder->titleInfo.length;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) != 0)
orderSize += 8;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) != 0)
orderSize += 8;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X) != 0)
orderSize += 8;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y) != 0)
orderSize += 8;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) != 0)
orderSize += 1;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) != 0)
orderSize += 4;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) != 0)
orderSize += 8;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) != 0)
orderSize += 8;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) != 0)
orderSize += 8;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) != 0)
orderSize += 2 + stateOrder->numWindowRects * sizeof(RECTANGLE_16);
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) != 0)
orderSize += 8;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) != 0)
orderSize += 2 + stateOrder->numVisibilityRects * sizeof(RECTANGLE_16);
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION) != 0)
orderSize += 2 + stateOrder->OverlayDescription.length;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON) != 0)
orderSize += 1;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER) != 0)
orderSize += 1;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE) != 0)
orderSize += 1;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE) != 0)
orderSize += 1;
return orderSize;
}
BOOL update_send_new_or_existing_window(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
const WINDOW_STATE_ORDER* stateOrder)
{
wStream* s;
rdpUpdate* update = context->update;
BYTE controlFlags = ORDER_SECONDARY | (ORDER_TYPE_WINDOW << 2);
UINT16 orderSize = 11;
size_t orderSizePos, orderEndPos;
UINT16 orderSize;
s = update->us;
if (!s)
return FALSE;
orderSize = update_calculate_new_or_existing_window(orderInfo, stateOrder);
if (!Stream_EnsureRemainingCapacity(s, orderSize))
return FALSE;
Stream_Write_UINT8(s, controlFlags); /* Header (1 byte) */
orderSizePos = Stream_GetPosition(s);
Stream_Seek_UINT16(s); /* OrderSize (2 bytes) */
Stream_Write_UINT16(s, orderSize); /* OrderSize (2 bytes) */
Stream_Write_UINT32(s, orderInfo->fieldFlags); /* FieldsPresentFlags (4 bytes) */
Stream_Write_UINT32(s, orderInfo->windowId); /* WindowID (4 bytes) */
orderSize = 11;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) != 0)
{
orderSize += 4;
Stream_Write_UINT32(s, stateOrder->ownerWindowId);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE) != 0)
{
orderSize += 8;
Stream_Write_UINT32(s, stateOrder->style);
Stream_Write_UINT32(s, stateOrder->extendedStyle);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW) != 0)
{
orderSize += 1;
Stream_Write_UINT8(s, stateOrder->showState);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) != 0)
{
orderSize += 2 + stateOrder->titleInfo.length;
Stream_Write_UINT16(s, stateOrder->titleInfo.length);
Stream_Write(s, stateOrder->titleInfo.string, stateOrder->titleInfo.length);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) != 0)
{
orderSize += 8;
Stream_Write_UINT32(s, stateOrder->clientOffsetX);
Stream_Write_UINT32(s, stateOrder->clientOffsetY);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) != 0)
{
orderSize += 8;
Stream_Write_UINT32(s, stateOrder->clientAreaWidth);
Stream_Write_UINT32(s, stateOrder->clientAreaHeight);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X) != 0)
{
orderSize += 8;
Stream_Write_UINT32(s, stateOrder->resizeMarginLeft);
Stream_Write_UINT32(s, stateOrder->resizeMarginRight);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y) != 0)
{
orderSize += 8;
Stream_Write_UINT32(s, stateOrder->resizeMarginTop);
Stream_Write_UINT32(s, stateOrder->resizeMarginBottom);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) != 0)
{
orderSize += 1;
Stream_Write_UINT8(s, stateOrder->RPContent);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) != 0)
{
orderSize += 4;
Stream_Write_UINT32(s, stateOrder->rootParentHandle);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) != 0)
{
orderSize += 8;
Stream_Write_UINT32(s, stateOrder->windowOffsetX);
Stream_Write_UINT32(s, stateOrder->windowOffsetY);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) != 0)
{
orderSize += 8;
Stream_Write_UINT32(s, stateOrder->windowClientDeltaX);
Stream_Write_UINT32(s, stateOrder->windowClientDeltaY);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) != 0)
{
orderSize += 8;
Stream_Write_UINT32(s, stateOrder->windowWidth);
Stream_Write_UINT32(s, stateOrder->windowHeight);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) != 0)
{
orderSize += 2 + stateOrder->numWindowRects * sizeof(RECTANGLE_16);
Stream_Write_UINT16(s, stateOrder->numWindowRects);
Stream_Write(s, stateOrder->windowRects, stateOrder->numWindowRects * sizeof(RECTANGLE_16));
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) != 0)
{
orderSize += 8;
Stream_Write_UINT32(s, stateOrder->visibleOffsetX);
Stream_Write_UINT32(s, stateOrder->visibleOffsetY);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) != 0)
{
orderSize += 2 + stateOrder->numVisibilityRects * sizeof(RECTANGLE_16);
Stream_Write_UINT16(s, stateOrder->numVisibilityRects);
Stream_Write(s, stateOrder->visibilityRects,
stateOrder->numVisibilityRects * sizeof(RECTANGLE_16));
@ -2147,7 +2202,6 @@ BOOL update_send_new_or_existing_window(rdpContext* context, const WINDOW_ORDER_
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION) != 0)
{
orderSize += 2 + stateOrder->OverlayDescription.length;
Stream_Write_UINT16(s, stateOrder->OverlayDescription.length);
Stream_Write(s, stateOrder->OverlayDescription.string,
stateOrder->OverlayDescription.length);
@ -2155,33 +2209,24 @@ BOOL update_send_new_or_existing_window(rdpContext* context, const WINDOW_ORDER_
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON) != 0)
{
orderSize += 1;
Stream_Write_UINT8(s, stateOrder->TaskbarButton);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER) != 0)
{
orderSize += 1;
Stream_Write_UINT8(s, stateOrder->EnforceServerZOrder);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE) != 0)
{
orderSize += 1;
Stream_Write_UINT8(s, stateOrder->AppBarState);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE) != 0)
{
orderSize += 1;
Stream_Write_UINT8(s, stateOrder->AppBarEdge);
}
/* Write size */
orderEndPos = Stream_GetPosition(s);
Stream_SetPosition(s, orderSizePos);
Stream_Write_UINT16(s, orderSize);
Stream_SetPosition(s, orderEndPos);
update->numberOrders++;
return TRUE;
}
@ -2198,24 +2243,40 @@ BOOL update_send_window_update(rdpContext* context, const WINDOW_ORDER_INFO* ord
return update_send_new_or_existing_window(context, orderInfo, stateOrder);
}
static UINT16 update_calculate_window_icon_order(const WINDOW_ORDER_INFO* orderInfo,
const WINDOW_ICON_ORDER* iconOrder)
{
UINT16 orderSize = 23;
ICON_INFO* iconInfo = iconOrder->iconInfo;
orderSize += iconInfo->cbBitsColor + iconInfo->cbBitsMask;
if (iconInfo->bpp <= 8)
orderSize += 2 + iconInfo->cbColorTable;
return orderSize;
}
BOOL update_send_window_icon(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
const WINDOW_ICON_ORDER* iconOrder)
{
wStream* s;
rdpUpdate* update = context->update;
BYTE controlFlags = ORDER_SECONDARY | (ORDER_TYPE_WINDOW << 2);
UINT16 orderSize = 23;
size_t orderSizePos, orderEndPos;
UINT16 orderSize;
ICON_INFO* iconInfo = iconOrder->iconInfo;
s = update->us;
if (!s)
if (!s || !iconInfo)
return FALSE;
orderSize = update_calculate_window_icon_order(orderInfo, iconOrder);
if (!Stream_EnsureRemainingCapacity(s, orderSize))
return FALSE;
/* Write Hdr */
Stream_Write_UINT8(s, controlFlags); /* Header (1 byte) */
orderSizePos = Stream_GetPosition(s);
Stream_Seek_UINT16(s); /* OrderSize (2 bytes) */
Stream_Write_UINT16(s, orderSize); /* OrderSize (2 bytes) */
Stream_Write_UINT32(s, orderInfo->fieldFlags); /* FieldsPresentFlags (4 bytes) */
Stream_Write_UINT32(s, orderInfo->windowId); /* WindowID (4 bytes) */
/* Write body */
@ -2228,27 +2289,19 @@ BOOL update_send_window_icon(rdpContext* context, const WINDOW_ORDER_INFO* order
if (iconInfo->bpp <= 8)
{
Stream_Write_UINT16(s, iconInfo->cbColorTable); /* CbColorTable (2 bytes) */
orderSize += 2;
}
Stream_Write_UINT16(s, iconInfo->cbBitsMask); /* CbBitsMask (2 bytes) */
Stream_Write_UINT16(s, iconInfo->cbBitsColor); /* CbBitsColor (2 bytes) */
Stream_Write(s, iconInfo->bitsMask, iconInfo->cbBitsMask); /* BitsMask (variable) */
orderSize += iconInfo->cbBitsMask;
if (iconInfo->bpp <= 8)
{
Stream_Write(s, iconInfo->colorTable, iconInfo->cbColorTable); /* ColorTable (variable) */
orderSize += iconInfo->cbColorTable;
}
Stream_Write(s, iconInfo->bitsColor, iconInfo->cbBitsColor); /* BitsColor (variable) */
orderSize += iconInfo->cbBitsColor;
/* Write size */
orderEndPos = Stream_GetPosition(s);
Stream_SetPosition(s, orderSizePos);
Stream_Write_UINT16(s, orderSize);
Stream_SetPosition(s, orderEndPos);
update->numberOrders++;
return TRUE;
}
@ -2266,6 +2319,9 @@ BOOL update_send_window_cached_icon(rdpContext* context, const WINDOW_ORDER_INFO
if (!s)
return FALSE;
if (!Stream_EnsureRemainingCapacity(s, orderSize))
return FALSE;
/* Write Hdr */
Stream_Write_UINT8(s, controlFlags); /* Header (1 byte) */
Stream_Write_UINT16(s, orderSize); /* OrderSize (2 bytes) */
@ -2289,6 +2345,9 @@ BOOL update_send_window_delete(rdpContext* context, const WINDOW_ORDER_INFO* ord
if (!s)
return FALSE;
if (!Stream_EnsureRemainingCapacity(s, orderSize))
return FALSE;
/* Write Hdr */
Stream_Write_UINT8(s, controlFlags); /* Header (1 byte) */
Stream_Write_UINT16(s, orderSize); /* OrderSize (2 bytes) */
@ -2298,6 +2357,48 @@ BOOL update_send_window_delete(rdpContext* context, const WINDOW_ORDER_INFO* ord
return TRUE;
}
static UINT16 update_calculate_new_or_existing_notification_icons_order(
const WINDOW_ORDER_INFO* orderInfo, const NOTIFY_ICON_STATE_ORDER* iconStateOrder)
{
UINT16 orderSize = 15;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) != 0)
orderSize += 4;
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) != 0)
{
orderSize += 2 + iconStateOrder->toolTip.length;
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) != 0)
{
NOTIFY_ICON_INFOTIP infoTip = iconStateOrder->infoTip;
orderSize += 12 + infoTip.text.length + infoTip.title.length;
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE) != 0)
{
orderSize += 4;
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_ICON) != 0)
{
ICON_INFO iconInfo = iconStateOrder->icon;
orderSize += 12;
if (iconInfo.bpp <= 8)
orderSize += 2 + iconInfo.cbColorTable;
orderSize += iconInfo.cbBitsMask + iconInfo.cbBitsColor;
}
else if ((orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON) != 0)
{
orderSize += 3;
}
return orderSize;
}
BOOL update_send_new_or_existing_notification_icons(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
const NOTIFY_ICON_STATE_ORDER* iconStateOrder)
@ -2305,18 +2406,22 @@ BOOL update_send_new_or_existing_notification_icons(rdpContext* context,
wStream* s;
rdpUpdate* update = context->update;
BYTE controlFlags = ORDER_SECONDARY | (ORDER_TYPE_WINDOW << 2);
UINT16 orderSize = 15;
size_t orderSizePos, orderEndPos;
UINT16 orderSize;
BOOL versionFieldPresent = FALSE;
s = update->us;
if (!s)
return FALSE;
orderSize =
update_calculate_new_or_existing_notification_icons_order(orderInfo, iconStateOrder);
if (!Stream_EnsureRemainingCapacity(s, orderSize))
return FALSE;
/* Write Hdr */
Stream_Write_UINT8(s, controlFlags); /* Header (1 byte) */
orderSizePos = Stream_GetPosition(s);
Stream_Seek_UINT16(s); /* OrderSize (2 bytes) */
Stream_Write_INT16(s, orderSize); /* OrderSize (2 bytes) */
Stream_Write_UINT32(s, orderInfo->fieldFlags); /* FieldsPresentFlags (4 bytes) */
Stream_Write_UINT32(s, orderInfo->windowId); /* WindowID (4 bytes) */
Stream_Write_UINT32(s, orderInfo->notifyIconId); /* NotifyIconId (4 bytes) */
@ -2325,14 +2430,11 @@ BOOL update_send_new_or_existing_notification_icons(rdpContext* context,
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) != 0)
{
versionFieldPresent = TRUE;
orderSize += 4;
Stream_Write_UINT32(s, iconStateOrder->version);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) != 0)
{
orderSize += 2 + iconStateOrder->toolTip.length;
Stream_Write_UINT16(s, iconStateOrder->toolTip.length);
Stream_Write(s, iconStateOrder->toolTip.string, iconStateOrder->toolTip.length);
}
@ -2345,7 +2447,6 @@ BOOL update_send_new_or_existing_notification_icons(rdpContext* context,
if (versionFieldPresent && iconStateOrder->version == 0)
return FALSE;
orderSize += 12 + infoTip.text.length + infoTip.title.length;
Stream_Write_UINT32(s, infoTip.timeout); /* Timeout (4 bytes) */
Stream_Write_UINT32(s, infoTip.flags); /* InfoFlags (4 bytes) */
Stream_Write_UINT16(s, infoTip.text.length); /* InfoTipText (variable) */
@ -2354,17 +2455,18 @@ BOOL update_send_new_or_existing_notification_icons(rdpContext* context,
Stream_Write(s, infoTip.title.string, infoTip.title.length);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE) != 0 &&
iconStateOrder->version != 0)
if ((orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE) != 0)
{
orderSize += 4;
/* notify state should not be sent when version is 0 */
if (versionFieldPresent && iconStateOrder->version == 0)
return FALSE;
Stream_Write_UINT32(s, iconStateOrder->state);
}
if ((orderInfo->fieldFlags & WINDOW_ORDER_ICON) != 0)
{
ICON_INFO iconInfo = iconStateOrder->icon;
orderSize += 12;
Stream_Write_UINT16(s, iconInfo.cacheEntry); /* CacheEntry (2 bytes) */
Stream_Write_UINT8(s, iconInfo.cacheId); /* CacheId (1 byte) */
Stream_Write_UINT8(s, iconInfo.bpp); /* Bpp (1 byte) */
@ -2374,7 +2476,6 @@ BOOL update_send_new_or_existing_notification_icons(rdpContext* context,
if (iconInfo.bpp <= 8)
{
Stream_Write_UINT16(s, iconInfo.cbColorTable); /* CbColorTable (2 bytes) */
orderSize += 2;
}
Stream_Write_UINT16(s, iconInfo.cbBitsMask); /* CbBitsMask (2 bytes) */
@ -2385,25 +2486,17 @@ BOOL update_send_new_or_existing_notification_icons(rdpContext* context,
if (iconInfo.bpp <= 8)
{
Stream_Write(s, iconInfo.colorTable, iconInfo.cbColorTable); /* ColorTable (variable) */
orderSize += iconInfo.cbColorTable;
}
Stream_Write(s, iconInfo.bitsColor, iconInfo.cbBitsColor); /* BitsColor (variable) */
orderSize += iconInfo.cbBitsColor;
}
else if ((orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON) != 0)
{
CACHED_ICON_INFO cachedIcon = iconStateOrder->cachedIcon;
orderSize += 3;
Stream_Write_UINT16(s, cachedIcon.cacheEntry); /* CacheEntry (2 bytes) */
Stream_Write_UINT8(s, cachedIcon.cacheId); /* CacheId (1 byte) */
}
/* Write size */
orderEndPos = Stream_GetPosition(s);
Stream_SetPosition(s, orderSizePos);
Stream_Write_UINT16(s, orderSize);
Stream_SetPosition(s, orderEndPos);
update->numberOrders++;
return TRUE;
}