Fixed settings pointer functions

* Bugfixes for offset gettern/setter
* Additional unit tests
This commit is contained in:
Armin Novak 2022-05-02 14:59:33 +02:00 committed by akallabeth
parent 7bb1bc08c2
commit bf7594c067
2 changed files with 375 additions and 46 deletions

View File

@ -1242,7 +1242,7 @@ BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, size_t id, const vo
freerdp_target_net_addresses_free(settings);
return freerdp_settings_set_pointer_len_(settings, FreeRDP_TargetNetAddresses,
FreeRDP_TargetNetAddressCount, data, len,
sizeof(char));
sizeof(char*));
case FreeRDP_TargetNetPorts:
if (data == NULL)
freerdp_target_net_addresses_free(settings);
@ -1333,62 +1333,144 @@ BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, size_t id, const vo
void* freerdp_settings_get_pointer_array_writable(const rdpSettings* settings, size_t id,
size_t offset)
{
size_t max;
if (!settings)
return NULL;
switch (id)
{
case FreeRDP_ClientAutoReconnectCookie:
max = 1;
if ((offset >= max) || !settings->ClientAutoReconnectCookie)
goto fail;
return &settings->ClientAutoReconnectCookie[offset];
case FreeRDP_ServerAutoReconnectCookie:
max = 1;
if ((offset >= max) || !settings->ServerAutoReconnectCookie)
goto fail;
return &settings->ServerAutoReconnectCookie[offset];
case FreeRDP_ServerCertificate:
max = freerdp_settings_get_uint32(settings, FreeRDP_ServerCertificateLength);
if (offset >= max)
goto fail;
return &settings->ServerCertificate[offset];
case FreeRDP_ServerRandom:
max = freerdp_settings_get_uint32(settings, FreeRDP_ServerRandomLength);
if (offset >= max)
goto fail;
return &settings->ServerRandom[offset];
case FreeRDP_ClientRandom:
max = freerdp_settings_get_uint32(settings, FreeRDP_ClientRandomLength);
if (offset >= max)
goto fail;
return &settings->ClientRandom[offset];
case FreeRDP_LoadBalanceInfo:
max = freerdp_settings_get_uint32(settings, FreeRDP_LoadBalanceInfoLength);
if (offset >= max)
goto fail;
return &settings->LoadBalanceInfo[offset];
case FreeRDP_RedirectionTsvUrl:
max = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionTsvUrlLength);
if (offset >= max)
goto fail;
return &settings->RedirectionTsvUrl[offset];
case FreeRDP_RedirectionPassword:
max = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionPasswordLength);
if (offset >= max)
goto fail;
return &settings->RedirectionPassword[offset];
case FreeRDP_OrderSupport:
if (offset >= 32)
return FALSE;
max = 32;
if (offset >= max)
goto fail;
return &settings->OrderSupport[offset];
case FreeRDP_MonitorIds:
if (offset > freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds))
return NULL;
max = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
if (offset >= max)
goto fail;
return &settings->MonitorIds[offset];
case FreeRDP_MonitorDefArray:
if (offset > freerdp_settings_get_uint32(settings, FreeRDP_MonitorDefArraySize))
return NULL;
max = freerdp_settings_get_uint32(settings, FreeRDP_MonitorDefArraySize);
if (offset >= max)
goto fail;
return &settings->MonitorDefArray[offset];
case FreeRDP_ChannelDefArray:
if (offset > freerdp_settings_get_uint32(settings, FreeRDP_ChannelDefArraySize))
return NULL;
max = freerdp_settings_get_uint32(settings, FreeRDP_ChannelDefArraySize);
if (offset >= max)
goto fail;
return &settings->ChannelDefArray[offset];
case FreeRDP_DeviceArray:
if (offset > freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize))
return NULL;
max = freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize);
if (offset >= max)
goto fail;
return &settings->DeviceArray[offset];
case FreeRDP_StaticChannelArray:
if (offset > freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize))
return NULL;
max = freerdp_settings_get_uint32(settings, FreeRDP_StaticChannelArraySize);
if (offset >= max)
goto fail;
return settings->StaticChannelArray[offset];
case FreeRDP_DynamicChannelArray:
if (offset > freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize))
return NULL;
max = freerdp_settings_get_uint32(settings, FreeRDP_DynamicChannelArraySize);
if (offset >= max)
goto fail;
return settings->DynamicChannelArray[offset];
case FreeRDP_FragCache:
if (offset >= 1)
return NULL;
max = 1;
if (offset >= max)
goto fail;
return &settings->FragCache[offset];
case FreeRDP_GlyphCache:
if (offset >= 10)
return NULL;
max = 10;
if (offset >= max)
goto fail;
return &settings->GlyphCache[offset];
case FreeRDP_BitmapCacheV2CellInfo:
/* TODO: BitmapCacheV2NumCells should be limited to 4
if (offset > freerdp_settings_get_uint32(settings, FreeRDP_BitmapCacheV2NumCells))
return NULL;
*/
max = freerdp_settings_get_uint32(settings, FreeRDP_BitmapCacheV2NumCells);
if (offset >= max)
goto fail;
return &settings->BitmapCacheV2CellInfo[offset];
case FreeRDP_ReceivedCapabilities:
if (offset > settings->ReceivedCapabilitiesSize)
return 0;
max = freerdp_settings_get_uint32(settings, FreeRDP_ReceivedCapabilitiesSize);
if (offset >= max)
goto fail;
return &settings->ReceivedCapabilities[offset];
case FreeRDP_TargetNetAddresses:
max = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount);
if (offset >= max)
goto fail;
return settings->TargetNetAddresses[offset];
case FreeRDP_TargetNetPorts:
max = freerdp_settings_get_uint32(settings, FreeRDP_TargetNetAddressCount);
if (offset >= max)
goto fail;
return settings->TargetNetPorts[offset];
case FreeRDP_ClientTimeZone:
max = 1;
if (offset >= max)
goto fail;
return settings->ClientTimeZone;
case FreeRDP_RdpServerCertificate:
max = 1;
if (offset >= max)
goto fail;
return settings->RdpServerCertificate;
case FreeRDP_RdpServerRsaKey:
max = 1;
if (offset >= max)
goto fail;
return settings->RdpServerRsaKey;
default:
WLog_WARN(TAG, "Invalid id %" PRIuz " for %s", id, __FUNCTION__);
WLog_WARN(TAG, "Invalid id %s [%" PRIuz "] for %s",
freerdp_settings_get_name_for_key(id), id, __FUNCTION__);
return NULL;
}
fail:
WLog_WARN(TAG, "Invalid offset for %s [%" PRIuz "]: size=%" PRIuz ", offset=%" PRIuz,
freerdp_settings_get_name_for_key(id), id, max, offset);
return NULL;
}
BOOL freerdp_settings_set_pointer_array(rdpSettings* settings, size_t id, size_t offset,
@ -1399,6 +1481,24 @@ BOOL freerdp_settings_set_pointer_array(rdpSettings* settings, size_t id, size_t
return FALSE;
switch (id)
{
case FreeRDP_ClientAutoReconnectCookie:
maxOffset = 1;
if ((offset >= maxOffset) || !data || !settings->ClientAutoReconnectCookie)
goto fail;
settings->ClientAutoReconnectCookie[offset] = *(const ARC_CS_PRIVATE_PACKET*)data;
return TRUE;
case FreeRDP_ServerAutoReconnectCookie:
maxOffset = 1;
if ((offset >= maxOffset) || !data || !settings->ServerAutoReconnectCookie)
goto fail;
settings->ServerAutoReconnectCookie[offset] = *(const ARC_SC_PRIVATE_PACKET*)data;
return TRUE;
case FreeRDP_ServerCertificate:
maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ServerCertificateLength);
if ((offset >= maxOffset) || !data)
goto fail;
settings->ServerCertificate[offset] = *(const BYTE*)data;
return TRUE;
case FreeRDP_DeviceArray:
maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_DeviceArraySize);
if (offset >= maxOffset)
@ -1434,25 +1534,64 @@ BOOL freerdp_settings_set_pointer_array(rdpSettings* settings, size_t id, size_t
settings->DynamicChannelArray[offset] = freerdp_addin_argv_clone(data);
return TRUE;
case FreeRDP_BitmapCacheV2CellInfo:
maxOffset = 5;
maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_BitmapCacheV2NumCells);
if ((offset >= maxOffset) || !data)
goto fail;
settings->BitmapCacheV2CellInfo[offset] = *(const BITMAP_CACHE_V2_CELL_INFO*)data;
{
const BITMAP_CACHE_V2_CELL_INFO* cdata = (const BITMAP_CACHE_V2_CELL_INFO*)data;
settings->BitmapCacheV2CellInfo[offset] = *cdata;
}
return TRUE;
case FreeRDP_ServerRandom:
maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ServerRandomLength);
if ((offset >= maxOffset) || !data)
goto fail;
settings->ServerRandom[offset] = *(const BYTE*)data;
return TRUE;
case FreeRDP_ClientRandom:
maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_ClientRandomLength);
if ((offset >= maxOffset) || !data)
goto fail;
settings->ClientRandom[offset] = *(const BYTE*)data;
return TRUE;
case FreeRDP_LoadBalanceInfo:
maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_LoadBalanceInfoLength);
if ((offset >= maxOffset) || !data)
goto fail;
settings->LoadBalanceInfo[offset] = *(const BYTE*)data;
return TRUE;
case FreeRDP_RedirectionTsvUrl:
maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionTsvUrlLength);
if ((offset >= maxOffset) || !data)
goto fail;
settings->RedirectionTsvUrl[offset] = *(const BYTE*)data;
return TRUE;
case FreeRDP_RedirectionPassword:
maxOffset = freerdp_settings_get_uint32(settings, FreeRDP_RedirectionPasswordLength);
if ((offset >= maxOffset) || !data)
goto fail;
settings->RedirectionPassword[offset] = *(const BYTE*)data;
return TRUE;
case FreeRDP_OrderSupport:
maxOffset = 32;
if (!settings->OrderSupport)
goto fail;
if ((offset >= maxOffset) || !data)
goto fail;
settings->OrderSupport[offset] = *(const BOOL*)data;
return TRUE;
case FreeRDP_GlyphCache:
maxOffset = 10;
if (!settings->GlyphCache)
goto fail;
if ((offset >= maxOffset) || !data)
goto fail;
settings->GlyphCache[offset] = *(const GLYPH_CACHE_DEFINITION*)data;
return TRUE;
case FreeRDP_FragCache:
maxOffset = 1;
if (!settings->FragCache)
goto fail;
if ((offset >= maxOffset) || !data)
goto fail;
settings->FragCache[offset] = *(const GLYPH_CACHE_DEFINITION*)data;
@ -1475,8 +1614,17 @@ BOOL freerdp_settings_set_pointer_array(rdpSettings* settings, size_t id, size_t
goto fail;
settings->MonitorDefArray[offset] = *(const rdpMonitor*)data;
return TRUE;
case FreeRDP_ClientTimeZone:
maxOffset = 1;
if ((offset >= maxOffset) || !data || !settings->ClientTimeZone)
goto fail;
settings->ClientTimeZone[0] = *(const TIME_ZONE_INFORMATION*)data;
return TRUE;
default:
WLog_WARN(TAG, "Invalid id %" PRIuz " for %s", id, __FUNCTION__);
WLog_WARN(TAG, "Invalid id %s [%" PRIuz "] for %s",
freerdp_settings_get_name_for_key(id), id, __FUNCTION__);
return FALSE;
}

View File

@ -672,21 +672,42 @@ static BOOL check_device_type(void)
};
const char* args[] = { "somename", "anothername", "3rdname", "4thname" };
const struct test_entry tests[] = {
{ 1, RDPDR_DTYP_SERIAL, 0, NULL }, { 1, RDPDR_DTYP_SERIAL, 0, args },
{ 1, RDPDR_DTYP_SERIAL, 1, args }, { 1, RDPDR_DTYP_SERIAL, 2, args },
{ 1, RDPDR_DTYP_SERIAL, 3, args }, { 1, RDPDR_DTYP_SERIAL, 4, args },
{ 1, RDPDR_DTYP_PARALLEL, 0, NULL }, { 1, RDPDR_DTYP_PARALLEL, 0, args },
{ 1, RDPDR_DTYP_PARALLEL, 1, args }, { 1, RDPDR_DTYP_PARALLEL, 2, args },
{ 1, RDPDR_DTYP_PARALLEL, 3, args }, { 1, RDPDR_DTYP_PARALLEL, 4, args },
{ 1, RDPDR_DTYP_PRINT, 0, NULL }, { 1, RDPDR_DTYP_PRINT, 0, args },
{ 1, RDPDR_DTYP_PRINT, 1, args }, { 1, RDPDR_DTYP_PRINT, 2, args },
{ 1, RDPDR_DTYP_PRINT, 3, args }, { 1, RDPDR_DTYP_PRINT, 4, args },
{ 1, RDPDR_DTYP_FILESYSTEM, 0, NULL }, { 1, RDPDR_DTYP_FILESYSTEM, 0, args },
{ 1, RDPDR_DTYP_FILESYSTEM, 1, args }, { 1, RDPDR_DTYP_FILESYSTEM, 2, args },
{ 1, RDPDR_DTYP_FILESYSTEM, 3, args }, { 1, RDPDR_DTYP_FILESYSTEM, 4, args },
{ 1, RDPDR_DTYP_SMARTCARD, 0, NULL }, { 1, RDPDR_DTYP_SMARTCARD, 0, args },
{ 1, RDPDR_DTYP_SMARTCARD, 1, args }, { 1, RDPDR_DTYP_SMARTCARD, 2, args },
{ 1, RDPDR_DTYP_SMARTCARD, 3, args }, { 1, RDPDR_DTYP_SMARTCARD, 4, args }
{ 1, RDPDR_DTYP_SERIAL, 0, NULL },
{ 1, RDPDR_DTYP_SERIAL, 0, args },
{ 1, RDPDR_DTYP_SERIAL, 1, args },
{ 1, RDPDR_DTYP_SERIAL, 2, args },
{ 1, RDPDR_DTYP_SERIAL, 3, args },
{ 1, RDPDR_DTYP_SERIAL, 4, args },
{ 1, RDPDR_DTYP_PARALLEL, 0, NULL },
{ 1, RDPDR_DTYP_PARALLEL, 0, args },
{ 1, RDPDR_DTYP_PARALLEL, 1, args },
{ 1, RDPDR_DTYP_PARALLEL, 2, args },
{ 1, RDPDR_DTYP_PARALLEL, 3, args },
{ 1, RDPDR_DTYP_PARALLEL, 4, args },
{ 1, RDPDR_DTYP_PRINT, 0, NULL },
{ 1, RDPDR_DTYP_PRINT, 0, args },
{ 1, RDPDR_DTYP_PRINT, 1, args },
{ 1, RDPDR_DTYP_PRINT, 2, args },
{ 1, RDPDR_DTYP_PRINT, 3, args },
{ 1, RDPDR_DTYP_PRINT, 4, args },
{ 1, RDPDR_DTYP_FILESYSTEM, 0, NULL },
{ 1, RDPDR_DTYP_FILESYSTEM, 0, args },
{ 1, RDPDR_DTYP_FILESYSTEM, 1, args },
{ 1, RDPDR_DTYP_FILESYSTEM, 2, args },
{ 1, RDPDR_DTYP_FILESYSTEM, 3, args },
{ 1, RDPDR_DTYP_FILESYSTEM, 4, args },
{ 1, RDPDR_DTYP_SMARTCARD, 0, NULL },
{ 1, RDPDR_DTYP_SMARTCARD, 0, args },
{ 1, RDPDR_DTYP_SMARTCARD, 1, args },
{ 1, RDPDR_DTYP_SMARTCARD, 2, args },
{ 1, RDPDR_DTYP_SMARTCARD, 3, args },
{ 1, RDPDR_DTYP_SMARTCARD, 4, args },
{ -3, 0x123, 0, NULL },
{ -3, 0x123, 0, args },
{ -3, 0x123, 1, args },
{ -3, 0x123, 2, args },
{ -3, 0x123, 3, args },
{ -3, 0x123, 4, args },
};
for (x = 0; x < ARRAYSIZE(tests); x++)
@ -699,6 +720,164 @@ static BOOL check_device_type(void)
return TRUE;
}
static BOOL check_offsets(rdpSettings* settings, size_t id, size_t min, size_t max, BOOL checkPtr)
{
size_t x;
WINPR_ASSERT(settings);
if (!freerdp_settings_get_pointer(settings, id))
return FALSE;
for (x = min; x < max; x++)
{
const void* ptr = freerdp_settings_get_pointer_array(settings, id, x);
if (!ptr && checkPtr)
return FALSE;
}
return TRUE;
}
static BOOL test_write_offsets(rdpSettings* settings, size_t id, size_t elementSize, size_t min,
size_t max)
{
size_t x;
WINPR_ASSERT(settings);
for (x = min; x < max; x++)
{
const void* ptr;
char buffer[8192] = { 0 };
winpr_RAND(buffer, sizeof(buffer));
if (!freerdp_settings_set_pointer_array(settings, id, x, buffer))
return FALSE;
ptr = freerdp_settings_get_pointer_array(settings, id, x);
if (!ptr)
return FALSE;
if (memcmp(ptr, buffer, elementSize) != 0)
return FALSE;
}
return TRUE;
}
static BOOL test_pointer_array(void)
{
struct pointer_test_case
{
BOOL checkPtr;
BOOL write;
size_t id;
SSIZE_T sizeId;
size_t size;
size_t elementSize;
};
size_t x;
const struct pointer_test_case tests[] = {
{ TRUE, FALSE, FreeRDP_DeviceArray, FreeRDP_DeviceArraySize, 32, sizeof(RDPDR_DEVICE*) },
{ FALSE, FALSE, FreeRDP_TargetNetAddresses, FreeRDP_TargetNetAddressCount, 33,
sizeof(char*) },
{ FALSE, FALSE, FreeRDP_TargetNetPorts, FreeRDP_TargetNetAddressCount, 33, sizeof(UINT32) },
{ FALSE, FALSE, FreeRDP_StaticChannelArray, FreeRDP_StaticChannelArraySize, 32,
sizeof(ADDIN_ARGV*) },
{ FALSE, FALSE, FreeRDP_DynamicChannelArray, FreeRDP_DynamicChannelArraySize, 33,
sizeof(ADDIN_ARGV*) },
{ TRUE, TRUE, FreeRDP_BitmapCacheV2CellInfo, FreeRDP_BitmapCacheV2NumCells, 5,
sizeof(BITMAP_CACHE_V2_CELL_INFO) },
{ FALSE, FALSE, FreeRDP_OrderSupport, -1, 32, sizeof(BYTE) },
{ FALSE, FALSE, FreeRDP_ReceivedCapabilities, -1, 32, sizeof(BYTE) },
{ TRUE, TRUE, FreeRDP_GlyphCache, -1, 10, sizeof(GLYPH_CACHE_DEFINITION) },
{ TRUE, TRUE, FreeRDP_FragCache, -1, 1, sizeof(GLYPH_CACHE_DEFINITION) },
{ TRUE, TRUE, FreeRDP_MonitorIds, FreeRDP_NumMonitorIds, 33, sizeof(UINT32) },
{ TRUE, TRUE, FreeRDP_ChannelDefArray, FreeRDP_ChannelDefArraySize, 42,
sizeof(CHANNEL_DEF) },
{ TRUE, TRUE, FreeRDP_MonitorDefArray, FreeRDP_MonitorDefArraySize, 33,
sizeof(rdpMonitor) },
{ TRUE, TRUE, FreeRDP_ClientTimeZone, -1, 1, sizeof(TIME_ZONE_INFORMATION) },
{ FALSE, FALSE, FreeRDP_RdpServerCertificate, -1, 1, sizeof(rdpCertificate*) },
//{ FALSE, FALSE, FreeRDP_RdpServerRsaKey, -1, 1, sizeof(rdpRsaKey*) },
{ TRUE, TRUE, FreeRDP_RedirectionPassword, FreeRDP_RedirectionPasswordLength, 42,
sizeof(char) },
{ TRUE, TRUE, FreeRDP_RedirectionTsvUrl, FreeRDP_RedirectionTsvUrlLength, 42,
sizeof(char) },
{ TRUE, TRUE, FreeRDP_LoadBalanceInfo, FreeRDP_LoadBalanceInfoLength, 42, sizeof(char) },
{ TRUE, TRUE, FreeRDP_ServerRandom, FreeRDP_ServerRandomLength, 42, sizeof(char) },
{ TRUE, TRUE, FreeRDP_ClientRandom, FreeRDP_ClientRandomLength, 42, sizeof(char) },
{ TRUE, TRUE, FreeRDP_ServerCertificate, FreeRDP_ServerCertificateLength, 42,
sizeof(char) },
{ TRUE, TRUE, FreeRDP_ClientAutoReconnectCookie, -1, 1, sizeof(ARC_CS_PRIVATE_PACKET) },
{ TRUE, TRUE, FreeRDP_ServerAutoReconnectCookie, -1, 1, sizeof(ARC_SC_PRIVATE_PACKET) }
};
BOOL rc = FALSE;
rdpSettings* settings = freerdp_settings_new(0);
if (!settings)
goto fail;
for (x = 0; x < ARRAYSIZE(tests); x++)
{
const struct pointer_test_case* cur = &tests[x];
if (!freerdp_settings_set_pointer_len(settings, cur->id, NULL, cur->size))
goto fail;
if (cur->sizeId >= 0)
{
const UINT32 s = freerdp_settings_get_uint32(settings, (size_t)cur->sizeId);
if (s != cur->size)
goto fail;
}
if (!check_offsets(settings, cur->id, 0, cur->size, cur->checkPtr))
goto fail;
if (check_offsets(settings, cur->id, cur->size, cur->size + 5, TRUE))
goto fail;
if (cur->write)
{
if (!test_write_offsets(settings, cur->id, cur->elementSize, 0, cur->size))
goto fail;
if (test_write_offsets(settings, cur->id, cur->elementSize, cur->size, cur->size + 5))
goto fail;
}
if (!freerdp_settings_set_pointer_len(settings, cur->id, NULL, 0))
goto fail;
if (cur->sizeId >= 0)
{
const UINT32 s = freerdp_settings_get_uint32(settings, (size_t)cur->sizeId);
if (s != 0)
goto fail;
}
if (check_offsets(settings, cur->id, 0, cur->size, cur->checkPtr))
goto fail;
if (cur->write)
{
if (test_write_offsets(settings, cur->id, cur->elementSize, 0, cur->size))
goto fail;
}
if (!freerdp_settings_set_pointer_len(settings, cur->id, NULL, cur->size))
goto fail;
if (cur->sizeId >= 0)
{
const UINT32 s = freerdp_settings_get_uint32(settings, (size_t)cur->sizeId);
if (s != cur->size)
goto fail;
}
if (!check_offsets(settings, cur->id, 0, cur->size, cur->checkPtr))
goto fail;
if (check_offsets(settings, cur->id, cur->size + 1, cur->size + 5, TRUE))
goto fail;
if (cur->write)
{
if (!test_write_offsets(settings, cur->id, cur->elementSize, 0, cur->size))
goto fail;
if (test_write_offsets(settings, cur->id, cur->elementSize, cur->size, cur->size + 5))
goto fail;
}
}
rc = TRUE;
fail:
freerdp_settings_free(settings);
return rc;
}
int TestSettings(int argc, char* argv[])
{
int rc = -1;
@ -719,6 +898,8 @@ int TestSettings(int argc, char* argv[])
return -1;
if (!check_device_type())
return -1;
if (!test_pointer_array())
return -1;
settings = freerdp_settings_new(0);