Unified strto[u]l in cmdline.c

To clean up code all integer conversions are now done by
a helper function with proper checks in place.
This commit is contained in:
Armin Novak 2018-11-22 16:28:30 +01:00
parent 2f8737d973
commit e6e87eb3b3

View File

@ -58,6 +58,46 @@ static BOOL copy_value(const char* value, char** dst)
return (*dst) != NULL;
}
static BOOL value_to_int(const char* value, LONGLONG* result, LONGLONG min, LONGLONG max)
{
long long rc;
if (!value || !result)
return FALSE;
errno = 0;
rc = _strtoi64(value, NULL, 0);
if (errno != 0)
return FALSE;
if ((rc < min) || (rc > max))
return FALSE;
*result = rc;
return TRUE;
}
static BOOL value_to_uint(const char* value, ULONGLONG* result, ULONGLONG min, ULONGLONG max)
{
unsigned long long rc;
if (!value || !result)
return FALSE;
errno = 0;
rc = _strtoui64(value, NULL, 0);
if (errno != 0)
return FALSE;
if ((rc < min) || (rc > max))
return FALSE;
*result = rc;
return TRUE;
}
BOOL freerdp_client_print_version(void)
{
printf("This is FreeRDP version %s (%s)\n", FREERDP_VERSION_FULL,
@ -955,12 +995,10 @@ BOOL freerdp_parse_hostname(const char* hostname, char** host, int* port)
if (p)
{
unsigned long val;
SSIZE_T length = (p - hostname);
errno = 0;
val = strtoul(p + 1, NULL, 0);
size_t length = (p - hostname);
LONGLONG val;
if ((errno != 0) || (val <= 0) || (val > UINT16_MAX))
if (!value_to_int(p + 1, &val, 1, UINT16_MAX))
return FALSE;
*host = (char*) calloc(length + 1UL, sizeof(char));
@ -970,7 +1008,7 @@ BOOL freerdp_parse_hostname(const char* hostname, char** host, int* port)
CopyMemory(*host, hostname, length);
(*host)[length] = '\0';
*port = val;
*port = (UINT16)val;
}
else
{
@ -1509,13 +1547,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (p)
{
unsigned long val = strtoul(&p[1], NULL, 0);
LONGLONG val;
if ((errno != 0) || (val == 0) || (val > UINT16_MAX))
if (!value_to_int(&p[1], &val, 1, UINT16_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
length = (int)(p - arg->Value);
settings->ServerPort = val;
settings->ServerPort = (UINT16)val;
if (!(settings->ServerHostname = (char*) calloc(length + 1UL, sizeof(char))))
return COMMAND_LINE_ERROR_MEMORY;
@ -1546,12 +1584,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (*(p2 + 1) == ':')
{
unsigned long val = strtoul(&p2[2], NULL, 0);
LONGLONG val;
if ((errno != 0) || (val == 0) || (val > UINT16_MAX))
if (!value_to_int(&p[2], &val, 0, UINT16_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->ServerPort = val;
settings->ServerPort = (UINT16)val;
}
printf("hostname %s port %"PRIu32"\n", settings->ServerHostname, settings->ServerPort);
@ -1618,21 +1656,21 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "w")
{
long val = strtol(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val <= 0) || (val > UINT16_MAX))
if (!value_to_int(arg->Value, &val, -1, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->DesktopWidth = val;
settings->DesktopWidth = (UINT32)val;
}
CommandLineSwitchCase(arg, "h")
{
long val = strtol(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val <= 0) || (val > UINT16_MAX))
if (!value_to_int(arg->Value, &val, -1, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->DesktopHeight = val;
settings->DesktopHeight = (UINT32)val;
}
CommandLineSwitchCase(arg, "size")
{
@ -1679,15 +1717,15 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
*p = '\0';
{
long val = strtol(str, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val < 0) || (val > 100))
if (!value_to_int(str, &val, 0, 100))
{
free(str);
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
settings->PercentScreen = val;
settings->PercentScreen = (UINT32)val;
}
}
@ -1737,12 +1775,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
for (i = 0; i < settings->NumMonitorIds; i++)
{
unsigned long val = strtoul(p[i], NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT16_MAX))
if (!value_to_int(p[i], &val, 0, UINT16_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->MonitorIds[i] = val;
settings->MonitorIds[i] = (UINT32)val;
}
free(p);
@ -1795,13 +1833,11 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "bpp")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if (errno != 0)
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->ColorDepth = val;
switch (settings->ColorDepth)
{
case 32:
@ -1809,6 +1845,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
case 16:
case 15:
case 8:
settings->ColorDepth = (UINT32)val;
break;
default:
@ -1843,9 +1880,9 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "kbd")
{
unsigned long id = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (id > UINT32_MAX) || (id == 0))
if (!value_to_int(arg->Value, &val, 1, UINT32_MAX))
{
const int rc = freerdp_map_keyboard_layout_name_to_id(arg->Value);
@ -1857,38 +1894,38 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
/* Found a valid mapping, reset errno */
id = (unsigned long)rc;
val = rc;
errno = 0;
}
settings->KeyboardLayout = (UINT32) id;
settings->KeyboardLayout = (UINT32) val;
}
CommandLineSwitchCase(arg, "kbd-type")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->KeyboardType = val;
settings->KeyboardType = (UINT32)val;
}
CommandLineSwitchCase(arg, "kbd-subtype")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->KeyboardSubType = val;
settings->KeyboardSubType = (UINT32)val;
}
CommandLineSwitchCase(arg, "kbd-fn-key")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->KeyboardFunctionKey = val;
settings->KeyboardFunctionKey = (UINT32)val;
}
CommandLineSwitchCase(arg, "u")
{
@ -1914,19 +1951,20 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (p)
{
unsigned long val = strtoul(&p[1], NULL, 0);
size_t s;
LONGLONG val;
if ((errno != 0) || (val == 0) || (val > UINT16_MAX))
if (!value_to_int(&p[1], &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
length = (int)(p - arg->Value);
settings->GatewayPort = val;
s = (p - arg->Value);
settings->GatewayPort = (UINT32)val;
if (!(settings->GatewayHostname = (char*) calloc(length + 1UL, sizeof(char))))
if (!(settings->GatewayHostname = (char*) calloc(s + 1UL, sizeof(char))))
return COMMAND_LINE_ERROR_MEMORY;
strncpy(settings->GatewayHostname, arg->Value, length);
settings->GatewayHostname[length] = '\0';
strncpy(settings->GatewayHostname, arg->Value, s);
settings->GatewayHostname[s] = '\0';
}
else
{
@ -2020,13 +2058,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (p)
{
unsigned long val = strtoul(&p[1], NULL, 0);
LONGLONG val;
if ((errno != 0) || (val == 0) || (val > UINT16_MAX))
if (!value_to_int(&p[1], &val, 0, UINT16_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
length = (p - arg->Value);
settings->ProxyPort = val;
settings->ProxyPort = (UINT16)val;
settings->ProxyHostname = (char*) malloc(length + 1);
strncpy(settings->ProxyHostname, arg->Value, length);
settings->ProxyHostname[length] = '\0';
@ -2084,8 +2122,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "gateway-usage-method")
{
long type = 0;
char* pEnd;
UINT32 type = 0;
if (_stricmp(arg->Value, "none") == 0)
type = TSC_PROXY_MODE_NONE_DIRECT;
@ -2097,13 +2134,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
type = TSC_PROXY_MODE_DEFAULT;
else
{
type = strtol(arg->Value, &pEnd, 10);
LONGLONG val;
if (errno != 0)
if (!value_to_int(arg->Value, &val, TSC_PROXY_MODE_NONE_DIRECT, TSC_PROXY_MODE_NONE_DETECT))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
freerdp_set_gateway_usage_method(settings, (UINT32) type);
freerdp_set_gateway_usage_method(settings, type);
}
CommandLineSwitchCase(arg, "app")
{
@ -2155,12 +2192,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "compression-level")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->CompressionLevel = val;
settings->CompressionLevel = (UINT32)val;
}
CommandLineSwitchCase(arg, "drives")
{
@ -2190,29 +2227,33 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "audio-mode")
{
long mode = strtol(arg->Value, NULL, 0);
LONGLONG val;
if (errno != 0)
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
if (mode == AUDIO_MODE_REDIRECT)
switch (val)
{
settings->AudioPlayback = TRUE;
}
else if (mode == AUDIO_MODE_PLAY_ON_SERVER)
{
settings->RemoteConsoleAudio = TRUE;
}
else if (mode == AUDIO_MODE_NONE)
{
settings->AudioPlayback = FALSE;
settings->RemoteConsoleAudio = FALSE;
case AUDIO_MODE_REDIRECT:
settings->AudioPlayback = TRUE;
break;
case AUDIO_MODE_PLAY_ON_SERVER:
settings->RemoteConsoleAudio = TRUE;
break;
case AUDIO_MODE_NONE:
settings->AudioPlayback = FALSE;
settings->RemoteConsoleAudio = FALSE;
break;
default:
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
}
CommandLineSwitchCase(arg, "network")
{
long type = 0;
char* pEnd;
int type = 0;
if (_stricmp(arg->Value, "modem") == 0)
type = CONNECTION_TYPE_MODEM;
@ -2234,10 +2275,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
else
{
type = strtol(arg->Value, &pEnd, 10);
LONGLONG val;
if (errno != 0)
if (!value_to_int(arg->Value, &val, 1, 7))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
type = (int)val;
}
if (!freerdp_set_connection_type(settings, type))
@ -2367,12 +2410,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "frame-ack")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->FrameAcknowledge = val;
settings->FrameAcknowledge = (UINT32)val;
}
CommandLineSwitchCase(arg, "nsc")
{
@ -2386,12 +2429,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "jpeg-quality")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > 100))
if (!value_to_int(arg->Value, &val, 0, 100))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->JpegQuality = val;
settings->JpegQuality = (UINT32)val;
}
#endif
CommandLineSwitchCase(arg, "nego")
@ -2407,13 +2450,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "pcid")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->SendPreconnectionPdu = TRUE;
settings->PreconnectionId = val;
settings->PreconnectionId = (UINT32)val;
}
CommandLineSwitchCase(arg, "sec")
{
@ -2539,12 +2582,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "tls-seclevel")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > 5))
if (!value_to_int(arg->Value, &val, 0, 5))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->TlsSecLevel = val;
settings->TlsSecLevel = (UINT32)val;
}
CommandLineSwitchCase(arg, "cert-name")
{
@ -2589,12 +2632,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "parent-window")
{
UINT64 val = _strtoui64(arg->Value, NULL, 0);
ULONGLONG val;
if (errno != 0)
if (!value_to_uint(arg->Value, &val, 0, UINT64_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->ParentWindowId = val;
settings->ParentWindowId = (UINT64)val;
}
CommandLineSwitchCase(arg, "bitmap-cache")
{
@ -2640,32 +2683,24 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "max-fast-path-size")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->MultifragMaxRequestSize = val;
settings->MultifragMaxRequestSize = (UINT32)val;
}
CommandLineSwitchCase(arg, "max-loop-time")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, -1, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->MaxTimeInCheckLoop = val;
if ((long) settings->MaxTimeInCheckLoop < 0)
{
WLog_ERR(TAG, "invalid max loop time: %s", arg->Value);
return COMMAND_LINE_ERROR;
}
if ((long) settings->MaxTimeInCheckLoop <= 0)
{
if (val < 0)
settings->MaxTimeInCheckLoop = 10 * 60 * 60 * 1000; /* 10 hours can be considered as infinite */
}
else
settings->MaxTimeInCheckLoop = (UINT32)val;
}
CommandLineSwitchCase(arg, "async-input")
{
@ -2701,15 +2736,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "auto-reconnect-max-retries")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, 0, 1000))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->AutoReconnectMaxRetries = val;
if (settings->AutoReconnectMaxRetries > 1000)
return COMMAND_LINE_ERROR;
settings->AutoReconnectMaxRetries = (UINT32)val;
}
CommandLineSwitchCase(arg, "reconnect-cookie")
{
@ -2735,30 +2767,30 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "pwidth")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->DesktopPhysicalWidth = val;
settings->DesktopPhysicalWidth = (UINT32)val;
}
CommandLineSwitchCase(arg, "pheight")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > UINT32_MAX))
if (!value_to_int(arg->Value, &val, 0, UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->DesktopPhysicalHeight = val;
settings->DesktopPhysicalHeight = (UINT32)val;
}
CommandLineSwitchCase(arg, "orientation")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val > INT16_MAX))
if (!value_to_int(arg->Value, &val, 0, UINT16_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->DesktopOrientation = val;
settings->DesktopOrientation = (UINT16)val;
}
CommandLineSwitchCase(arg, "old-license")
{
@ -2766,55 +2798,49 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "scale")
{
unsigned long scaleFactor = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if (errno != 0)
if (!value_to_int(arg->Value, &val, 100, 180))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
if (scaleFactor == 100 || scaleFactor == 140 || scaleFactor == 180)
switch (val)
{
settings->DesktopScaleFactor = scaleFactor;
settings->DeviceScaleFactor = scaleFactor;
}
else
{
WLog_ERR(TAG, "scale: invalid scale factor (%d)", scaleFactor);
return COMMAND_LINE_ERROR;
case 100:
case 140:
case 180:
settings->DeviceScaleFactor = (UINT32)val;
break;
default:
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
}
CommandLineSwitchCase(arg, "scale-desktop")
{
unsigned long desktopScaleFactor = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if (errno != 0)
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
if (!value_to_int(arg->Value, &val, 100, 500))
return FALSE;
if (desktopScaleFactor >= 100 && desktopScaleFactor <= 500)
{
settings->DesktopScaleFactor = desktopScaleFactor;
}
else
{
WLog_ERR(TAG, "scale: invalid desktop scale factor (%d)", desktopScaleFactor);
return COMMAND_LINE_ERROR;
}
settings->DesktopScaleFactor = (UINT32)val;
}
CommandLineSwitchCase(arg, "scale-device")
{
unsigned long deviceScaleFactor = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if (errno != 0)
if (!value_to_int(arg->Value, &val, 100, 180))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
if (deviceScaleFactor == 100 || deviceScaleFactor == 140
|| deviceScaleFactor == 180)
switch (val)
{
settings->DeviceScaleFactor = deviceScaleFactor;
}
else
{
WLog_ERR(TAG, "scale: invalid device scale factor (%d)", deviceScaleFactor);
return COMMAND_LINE_ERROR;
case 100:
case 140:
case 180:
settings->DeviceScaleFactor = (UINT32)val;
break;
default:
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
}
CommandLineSwitchCase(arg, "action-script")
@ -2920,12 +2946,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT)
{
unsigned long val = strtoul(arg->Value, NULL, 0);
LONGLONG val;
if ((errno != 0) || (val == 0) || (val > UINT16_MAX))
if (!value_to_int(arg->Value, &val, 1, UINT16_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->ServerPort = val;
settings->ServerPort = (UINT32)val;
}
arg = CommandLineFindArgumentA(args, "p");