Merge pull request #4297 from akallabeth/cmd_parser_hardening

Fix #4296: Hardened command line post filter.
This commit is contained in:
Martin Fleisz 2017-12-05 14:40:03 +01:00 committed by GitHub
commit 876a7697be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 248 additions and 217 deletions

View File

@ -30,6 +30,7 @@
#include <winpr/crt.h>
#include <winpr/wlog.h>
#include <winpr/cmdline.h>
#include <winpr/path.h>
#include <freerdp/addin.h>
#include <freerdp/settings.h>
@ -397,7 +398,7 @@ BOOL freerdp_client_add_device_channel(rdpSettings* settings, int count,
if (count > 2)
{
if (!(drive->Path = _strdup(params[2])))
if (!PathFileExistsA(params[2]) || !(drive->Path = _strdup(params[2])))
{
free(drive->Name);
free(drive);
@ -736,75 +737,101 @@ error_argv:
return FALSE;
}
static char** freerdp_command_line_parse_comma_separated_values(char* list,
int* count)
static char** freerdp_command_line_parse_comma_separated_values_ex(const char* name, const char* list,
size_t* count)
{
char** p;
char* str;
int nArgs;
int index;
int nCommas;
size_t nArgs;
size_t index;
size_t nCommas;
size_t prefix, len;
nCommas = 0;
assert(NULL != count);
*count = 0;
if (!list)
return NULL;
{
if (name)
{
p = (char**) calloc(1UL, sizeof(char*));
for (index = 0; list[index]; index++)
nCommas += (list[index] == ',') ? 1 : 0;
if (p)
{
p[0] = name;
*count = 1;
return p;
}
}
return NULL;
}
{
const char* it = list;
while((it = strchr(it, ',')) != NULL)
{
it++;
nCommas++;
}
}
nArgs = nCommas + 1;
p = (char**) calloc((nArgs + 1UL), sizeof(char*));
if (name)
nArgs++;
prefix = (nArgs + 1UL) * sizeof(char*);
len = strlen(list);
p = (char**) calloc(len + prefix + 1, sizeof(char));
if (!p)
return NULL;
str = (char*) list;
p[0] = str;
str = &((char*)p)[prefix];
memcpy(str, list, len);
for (index = 1; index < nArgs; index++)
if (name)
p[0] = (char*)name;
for (index = name ? 1 : 0; index < nArgs; index++)
{
p[index] = strchr(p[index - 1], ',');
*p[index] = '\0';
p[index]++;
char* comma = strchr(str, ',');
p[index] = str;
if (comma)
{
str = comma + 1;
*comma = '\0';
}
}
p[index] = str + strlen(str);
*count = nArgs;
return p;
}
static char** freerdp_command_line_parse_comma_separated_values_offset(
char* list, int* count)
static char** freerdp_command_line_parse_comma_separated_values(char* list,
size_t* count)
{
char** p;
char** t;
p = freerdp_command_line_parse_comma_separated_values(list, count);
t = (char**) realloc(p, sizeof(char*) * (*count + 1));
return freerdp_command_line_parse_comma_separated_values_ex(NULL, list, count);
}
if (!t)
return NULL;
p = t;
if (*count)
MoveMemory(&p[1], p, sizeof(char*)** count);
(*count)++;
return p;
static char** freerdp_command_line_parse_comma_separated_values_offset(
const char* name, char* list, size_t* count)
{
return freerdp_command_line_parse_comma_separated_values_ex(name, list, count);
}
static int freerdp_client_command_line_post_filter(void* context,
COMMAND_LINE_ARGUMENT_A* arg)
{
rdpSettings* settings = (rdpSettings*) context;
BOOL status = FALSE;
BOOL status = TRUE;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "a")
{
char** p;
int count;
size_t count;
p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count);
if ((status = freerdp_client_add_device_channel(settings, count, p)))
@ -817,7 +844,7 @@ static int freerdp_client_command_line_post_filter(void* context,
CommandLineSwitchCase(arg, "vc")
{
char** p;
int count;
size_t count;
p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count);
status = freerdp_client_add_static_channel(settings, count, p);
free(p);
@ -825,7 +852,7 @@ static int freerdp_client_command_line_post_filter(void* context,
CommandLineSwitchCase(arg, "dvc")
{
char** p;
int count;
size_t count;
p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count);
status = freerdp_client_add_dynamic_channel(settings, count, p);
free(p);
@ -833,71 +860,54 @@ static int freerdp_client_command_line_post_filter(void* context,
CommandLineSwitchCase(arg, "drive")
{
char** p;
int count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value,
size_t count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Name, arg->Value,
&count);
p[0] = "drive";
status = freerdp_client_add_device_channel(settings, count, p);
free(p);
}
CommandLineSwitchCase(arg, "serial")
{
char** p;
int count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value,
size_t count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Name, arg->Value,
&count);
p[0] = "serial";
status = freerdp_client_add_device_channel(settings, count, p);
free(p);
}
CommandLineSwitchCase(arg, "parallel")
{
char** p;
int count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value,
size_t count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Name, arg->Value,
&count);
p[0] = "parallel";
status = freerdp_client_add_device_channel(settings, count, p);
free(p);
}
CommandLineSwitchCase(arg, "smartcard")
{
char** p;
int count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value,
size_t count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Name, arg->Value,
&count);
p[0] = "smartcard";
status = freerdp_client_add_device_channel(settings, count, p);
free(p);
}
CommandLineSwitchCase(arg, "printer")
{
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
{
char** p;
int count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value,
&count);
p[0] = "printer";
status = freerdp_client_add_device_channel(settings, count, p);
free(p);
}
else
{
char* p[1];
int count;
count = 1;
p[0] = "printer";
status = freerdp_client_add_device_channel(settings, count, p);
}
char** p;
size_t count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Name, arg->Value,
&count);
status = freerdp_client_add_device_channel(settings, count, p);
free(p);
}
CommandLineSwitchCase(arg, "usb")
{
char** p;
int count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value,
size_t count;
p = freerdp_command_line_parse_comma_separated_values_offset("urbdrc", arg->Value,
&count);
p[0] = "urbdrc";
status = freerdp_client_add_dynamic_channel(settings, count, p);
free(p);
}
@ -923,66 +933,30 @@ static int freerdp_client_command_line_post_filter(void* context,
}
CommandLineSwitchCase(arg, "sound")
{
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
{
char** p;
int count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value,
&count);
p[0] = "rdpsnd";
status = freerdp_client_add_static_channel(settings, count, p);
free(p);
}
else
{
char* p[1];
int count;
count = 1;
p[0] = "rdpsnd";
status = freerdp_client_add_static_channel(settings, count, p);
}
char** p;
size_t count;
p = freerdp_command_line_parse_comma_separated_values_offset("rdpsnd", arg->Value,
&count);
status = freerdp_client_add_static_channel(settings, count, p);
free(p);
}
CommandLineSwitchCase(arg, "microphone")
{
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
{
char** p;
int count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value,
&count);
p[0] = "audin";
status = freerdp_client_add_dynamic_channel(settings, count, p);
free(p);
}
else
{
char* p[1];
int count;
count = 1;
p[0] = "audin";
status = freerdp_client_add_dynamic_channel(settings, count, p);
}
char** p;
size_t count;
p = freerdp_command_line_parse_comma_separated_values_offset("audin", arg->Value,
&count);
status = freerdp_client_add_dynamic_channel(settings, count, p);
free(p);
}
CommandLineSwitchCase(arg, "multimedia")
{
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
{
char** p;
int count;
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value,
&count);
p[0] = "tsmf";
status = freerdp_client_add_dynamic_channel(settings, count, p);
free(p);
}
else
{
char* p[1];
int count;
count = 1;
p[0] = "tsmf";
status = freerdp_client_add_dynamic_channel(settings, count, p);
}
char** p;
size_t count;
p = freerdp_command_line_parse_comma_separated_values_offset("tsmf", arg->Value,
&count);
status = freerdp_client_add_dynamic_channel(settings, count, p);
free(p);
}
CommandLineSwitchCase(arg, "heartbeat")
{
@ -999,7 +973,7 @@ static int freerdp_client_command_line_post_filter(void* context,
settings->PasswordIsSmartcardPin = TRUE;
}
CommandLineSwitchEnd(arg)
return status ? 1 : 0;
return status ? 1 : -1;
}
BOOL freerdp_parse_username(char* username, char** user, char** domain)
@ -1250,8 +1224,8 @@ static int freerdp_detect_command_line_pre_filter(void* context, int index,
return 0;
}
int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv,
int* count, BOOL ignoreUnknown)
static int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv,
size_t* count, BOOL ignoreUnknown)
{
int status;
DWORD flags;
@ -1292,7 +1266,7 @@ int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv,
}
int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv,
int* count, BOOL ignoreUnknown)
size_t* count, BOOL ignoreUnknown)
{
int status;
DWORD flags;
@ -1339,9 +1313,9 @@ static BOOL freerdp_client_detect_command_line(int argc, char** argv,
int old_cli_status;
int old_cli_count;
int posix_cli_status;
int posix_cli_count;
size_t posix_cli_count;
int windows_cli_status;
int windows_cli_count;
size_t windows_cli_count;
BOOL compatibility = FALSE;
windows_cli_status = freerdp_detect_windows_style_command_line_syntax(argc,
argv, &windows_cli_count, ignoreUnknown);
@ -1477,7 +1451,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
char* user = NULL;
char* gwUser = NULL;
char* str;
int length;
size_t length;
int status;
DWORD flags;
BOOL promptForPassword = FALSE;
@ -1748,7 +1722,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
{
UINT32 i;
char** p;
int count = 0;
size_t count = 0;
p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count);
if (!p)
@ -2440,7 +2414,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
{
UINT32 i;
char** p;
int count = 0;
size_t count = 0;
p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count);
for (i = 0; i < count; i++)

View File

@ -41,7 +41,7 @@
#define TAG CLIENT_TAG("common.compatibility")
COMMAND_LINE_ARGUMENT_A old_args[] =
static COMMAND_LINE_ARGUMENT_A old_args[] =
{
{ "0", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "connect to console session" },
{ "a", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "set color depth in bits, default is 16" },
@ -93,7 +93,7 @@ COMMAND_LINE_ARGUMENT_A old_args[] =
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
BOOL freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32* ServerPort)
static BOOL freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32* ServerPort)
{
char* p;
char* host = NULL;
@ -152,7 +152,7 @@ BOOL freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32*
return TRUE;
}
int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args)
static int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args)
{
int args_handled = 0;
@ -231,7 +231,8 @@ int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args)
return args_handled;
}
int freerdp_client_old_command_line_pre_filter(void* context, int index, int argc, LPCSTR* argv)
static int freerdp_client_old_command_line_pre_filter(void* context, int index, int argc,
LPCSTR* argv)
{
rdpSettings* settings = (rdpSettings*) context;
@ -399,7 +400,7 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
return 0;
}
int freerdp_client_old_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT_A* arg)
static int freerdp_client_old_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT_A* arg)
{
return 0;
}
@ -521,7 +522,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
unsigned long val = strtoul(arg->Value, NULL, 0);
if ((errno != 0) || (val > INT8_MAX))
return FALSE;
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->ColorDepth = val;
WLog_WARN(TAG, "-a %s -> /bpp:%s", arg->Value, arg->Value);
@ -571,7 +572,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
if ((errno != 0) || (w == 0) || (w > UINT16_MAX))
{
free(str);
return FALSE;
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
h = strtoul(&p[1], NULL, 0);
@ -579,7 +580,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
if ((errno != 0) || (h == 0) || (h > UINT16_MAX))
{
free(str);
return FALSE;
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
*p = '\0';
@ -862,5 +863,5 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
WLog_WARN(TAG, " /port:%"PRIu32"", settings->ServerPort);
WLog_WARN(TAG, "");
return 1;
return 0;
}

View File

@ -4,31 +4,41 @@
#include <winpr/cmdline.h>
#include <winpr/spec.h>
#define TESTCASE(cmd, expected_return) \
{ \
rdpSettings* settings = freerdp_settings_new(0); \
status = freerdp_client_settings_parse_command_line(settings, ARRAYSIZE(cmd), cmd, FALSE); \
freerdp_settings_free(settings); \
if (status != expected_return) { \
printf("Test argument %s failed\n", #cmd); \
return -1; \
} \
}
#define TESTCASE_SUCCESS(cmd) \
{ \
rdpSettings* settings = freerdp_settings_new(0); \
status = freerdp_client_settings_parse_command_line(settings, ARRAYSIZE(cmd), cmd, FALSE); \
freerdp_settings_free(settings); \
if (status < 0) { \
printf("Test argument %s failed\n", #cmd); \
return -1; \
} \
}
int TestClientCmdLine(int argc, char* argv[])
#define TESTCASE(argv, ret_val) TESTCASE_impl(#argv, argv, ARRAYSIZE(argv), ret_val)
#define TESTCASE_SUCCESS(argv) TESTCASE_impl(#argv, argv, ARRAYSIZE(argv), 0)
static INLINE BOOL TESTCASE_impl(const char* name, char** argv, size_t argc,
int expected_return)
{
int status;
rdpSettings* settings = freerdp_settings_new(0);
printf("Running test %s\n", name);
if (!settings)
{
fprintf(stderr, "Test %s could not allocate settings!\n", name);
return FALSE;
}
status = freerdp_client_settings_parse_command_line(settings, argc, argv, FALSE);
freerdp_settings_free(settings);
if (status != expected_return)
{
fprintf(stderr, "Test %s failed!\n", name);
return FALSE;
}
return TRUE;
}
#if defined(_WIN32)
#define DRIVE_REDIRECT_PATH "c:\\Windows"
#else
#define DRIVE_REDIRECT_PATH "/tmp"
#endif
int TestClientCmdLine(int argc, char* argv[])
{
int rc = -1;
char* cmd1[] = {"xfreerdp", "--help"};
char* cmd2[] = {"xfreerdp", "/help"};
char* cmd3[] = {"xfreerdp", "-help"};
@ -39,8 +49,8 @@ int TestClientCmdLine(int argc, char* argv[])
char* cmd8[] = {"xfreerdp", "-v", "test.freerdp.com"};
char* cmd9[] = {"xfreerdp", "--v", "test.freerdp.com"};
char* cmd10[] = {"xfreerdp", "/v:test.freerdp.com"};
char* cmd11[] = {"xfreerdp", "--plugin", "rdpsnd", "--plugin", "rdpdr", "--data", "disk:media:/tmp", "--", "test.freerdp.com" };
char* cmd12[] = {"xfreerdp", "/sound", "/drive:media:/tmp", "/v:test.freerdp.com" };
char* cmd11[] = {"xfreerdp", "--plugin", "rdpsnd", "--plugin", "rdpdr", "--data", "disk:media:"DRIVE_REDIRECT_PATH, "--", "test.freerdp.com" };
char* cmd12[] = {"xfreerdp", "/sound", "/drive:media,"DRIVE_REDIRECT_PATH, "/v:test.freerdp.com" };
char* cmd13[] = {"xfreerdp", "-u", "test", "-p", "test", "test.freerdp.com"};
char* cmd14[] = {"xfreerdp", "-u", "test", "-p", "test", "-v", "test.freerdp.com"};
char* cmd15[] = {"xfreerdp", "/u:test", "/p:test", "/v:test.freerdp.com"};
@ -48,60 +58,99 @@ int TestClientCmdLine(int argc, char* argv[])
char* cmd17[] = {"xfreerdp", "--invalid"};
char* cmd18[] = {"xfreerdp", "/kbd-list"};
char* cmd19[] = {"xfreerdp", "/monitor-list"};
char* cmd20[] = {"xfreerdp", "/sound", "/drive:media:"DRIVE_REDIRECT_PATH, "/v:test.freerdp.com" };
char* cmd21[] = {"xfreerdp", "/sound", "/drive:media,/foo/bar/blabla", "/v:test.freerdp.com" };
TESTCASE(cmd1, COMMAND_LINE_STATUS_PRINT_HELP);
if (!TESTCASE(cmd1, COMMAND_LINE_STATUS_PRINT_HELP))
goto fail;
TESTCASE(cmd2, COMMAND_LINE_STATUS_PRINT_HELP);
if (!TESTCASE(cmd2, COMMAND_LINE_STATUS_PRINT_HELP))
goto fail;
TESTCASE(cmd3, COMMAND_LINE_STATUS_PRINT_HELP);
if (!TESTCASE(cmd3, COMMAND_LINE_STATUS_PRINT_HELP))
goto fail;
TESTCASE(cmd4, COMMAND_LINE_STATUS_PRINT_VERSION);
if (!TESTCASE(cmd4, COMMAND_LINE_STATUS_PRINT_VERSION))
goto fail;
TESTCASE(cmd5, COMMAND_LINE_STATUS_PRINT_VERSION);
if (!TESTCASE(cmd5, COMMAND_LINE_STATUS_PRINT_VERSION))
goto fail;
TESTCASE(cmd6, COMMAND_LINE_STATUS_PRINT_VERSION);
if (!TESTCASE(cmd6, COMMAND_LINE_STATUS_PRINT_VERSION))
goto fail;
TESTCASE_SUCCESS(cmd7);
if (!TESTCASE_SUCCESS(cmd7))
goto fail;
TESTCASE_SUCCESS(cmd8);
if (!TESTCASE_SUCCESS(cmd8))
goto fail;
TESTCASE_SUCCESS(cmd9);
if (!TESTCASE_SUCCESS(cmd9))
goto fail;
TESTCASE_SUCCESS(cmd10);
if (!TESTCASE_SUCCESS(cmd10))
goto fail;
TESTCASE_SUCCESS(cmd11);
if (!TESTCASE_SUCCESS(cmd11))
goto fail;
TESTCASE_SUCCESS(cmd12);
if (!TESTCASE_SUCCESS(cmd12))
goto fail;
// password gets overwritten therefore it need to be writeable
cmd13[4] = calloc(5, sizeof(char));
strncpy(cmd13[4], "test", 4);
TESTCASE_SUCCESS(cmd13);
cmd13[4] = _strdup("test");
cmd14[4] = _strdup("test");
cmd15[2] = _strdup("/p:test");
if (!cmd13[4] || !cmd14[4] || !cmd15[2])
goto free_arg;
if (!TESTCASE_SUCCESS(cmd13))
goto free_arg;
if (memcmp(cmd13[4], "****", 4) != 0)
goto free_arg;
if (!TESTCASE_SUCCESS(cmd14))
goto free_arg;
if (memcmp(cmd14[4], "****", 4) != 0)
goto free_arg;
if (!TESTCASE_SUCCESS(cmd15))
goto free_arg;
if (memcmp(cmd15[2], "/p:****", 7) != 0)
goto free_arg;
if (!TESTCASE(cmd16, COMMAND_LINE_ERROR_NO_KEYWORD))
goto free_arg;
if (!TESTCASE(cmd17, COMMAND_LINE_ERROR_NO_KEYWORD))
goto free_arg;
if (!TESTCASE(cmd18, COMMAND_LINE_STATUS_PRINT))
goto free_arg;
if (!TESTCASE(cmd19, COMMAND_LINE_STATUS_PRINT))
goto free_arg;
if (!TESTCASE(cmd20, COMMAND_LINE_ERROR))
goto free_arg;
if (!TESTCASE(cmd21, COMMAND_LINE_ERROR))
goto free_arg;
rc = 0;
free_arg:
free(cmd13[4]);
cmd14[4] = calloc(5, sizeof(char));
strncpy(cmd14[4], "test", 4);
TESTCASE_SUCCESS(cmd14);
free(cmd14[4]);
cmd15[2] = calloc(7, sizeof(char));
strncpy(cmd15[2], "/p:test", 6);
TESTCASE_SUCCESS(cmd15);
free(cmd15[2]);
TESTCASE(cmd16, COMMAND_LINE_ERROR_NO_KEYWORD);
TESTCASE(cmd17, COMMAND_LINE_ERROR_NO_KEYWORD);
TESTCASE(cmd18, COMMAND_LINE_STATUS_PRINT);
TESTCASE(cmd19, COMMAND_LINE_STATUS_PRINT);
#if 0
char* cmd20[] = {"-z --plugin cliprdr --plugin rdpsnd --data alsa latency:100 -- --plugin rdpdr --data disk:w7share:/home/w7share -- --plugin drdynvc --data tsmf:decoder:gstreamer -- -u test host.example.com"};
TESTCASE(cmd20, COMMAND_LINE_STATUS_PRINT);
#endif
return 0;
fail:
return rc;
}

View File

@ -54,17 +54,15 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
int count;
size_t length;
BOOL notescaped;
char* sigil;
const char* sigil;
size_t sigil_length;
char* keyword;
const char* keyword;
SSIZE_T keyword_length;
SSIZE_T keyword_index;
char* separator;
char* value;
const char* value;
int toggle;
status = 0;
notescaped = FALSE;
if (!argv)
@ -76,6 +74,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
status = 0;
else
status = COMMAND_LINE_STATUS_PRINT_HELP;
return status;
}
@ -101,7 +100,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
}
}
sigil = (char*) argv[i];
sigil = argv[i];
length = strlen(argv[i]);
if ((sigil[0] == '/') && (flags & COMMAND_LINE_SIGIL_SLASH))
@ -151,12 +150,12 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
{
if ((flags & COMMAND_LINE_IGN_UNKNOWN_KEYWORD))
continue;
return COMMAND_LINE_ERROR_NO_KEYWORD;
}
keyword_index = sigil_length;
keyword = (char*) &argv[i][keyword_index];
keyword = &argv[i][keyword_index];
toggle = -1;
if (flags & COMMAND_LINE_SIGIL_ENABLE_DISABLE)
@ -165,13 +164,13 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
{
toggle = TRUE;
keyword_index += 7;
keyword = (char*) &argv[i][keyword_index];
keyword = &argv[i][keyword_index];
}
else if (strncmp(keyword, "disable-", 8) == 0)
{
toggle = FALSE;
keyword_index += 8;
keyword = (char*) &argv[i][keyword_index];
keyword = &argv[i][keyword_index];
}
}
@ -188,12 +187,11 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
SSIZE_T separator_index = (separator - argv[i]);
SSIZE_T value_index = separator_index + 1;
keyword_length = (separator - keyword);
value = (char*) &argv[i][value_index];
value = &argv[i][value_index];
}
else
{
keyword_length = (length - keyword_index);
value = NULL;
}
@ -253,10 +251,11 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
argument = TRUE;
else
argument = FALSE;
if (value_present && argument)
{
i++;
value = (char*) argv[i];
value = argv[i];
}
else if (!value_present && (options[j].Flags & COMMAND_LINE_VALUE_OPTIONAL))
{
@ -326,7 +325,15 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
}
if (postFilter)
postFilter(context, &options[j]);
{
count = postFilter(context, &options[j]);
if (count < 0)
{
status = COMMAND_LINE_ERROR;
return status;
}
}
if (options[j].Flags & COMMAND_LINE_PRINT)
return COMMAND_LINE_STATUS_PRINT;
@ -337,6 +344,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
else if (options[j].Flags & COMMAND_LINE_PRINT_BUILDCONFIG)
return COMMAND_LINE_STATUS_PRINT_BUILDCONFIG;
}
if (!found && (flags & COMMAND_LINE_IGN_UNKNOWN_KEYWORD) == 0)
return COMMAND_LINE_ERROR_NO_KEYWORD;
}
@ -354,7 +362,7 @@ int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_ARGUMENT_W*
int CommandLineClearArgumentsA(COMMAND_LINE_ARGUMENT_A* options)
{
int i;
size_t i;
for (i = 0; options[i].Name != NULL; i++)
{
@ -419,7 +427,6 @@ COMMAND_LINE_ARGUMENT_W* CommandLineFindArgumentW(COMMAND_LINE_ARGUMENT_W* optio
COMMAND_LINE_ARGUMENT_A* CommandLineFindNextArgumentA(COMMAND_LINE_ARGUMENT_A* argument)
{
COMMAND_LINE_ARGUMENT_A* nextArgument;
nextArgument = &argument[1];
if (nextArgument->Name == NULL)