diff --git a/client/common/cmdline.c b/client/common/cmdline.c index a681d3d2e..e1a893f75 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -870,6 +870,8 @@ int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv, int* detect_status = 0; CommandLineClearArgumentsA(args); status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, NULL, NULL, NULL); + if (status < 0) + return status; arg = args; @@ -903,6 +905,8 @@ int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, int* c detect_status = 0; CommandLineClearArgumentsA(args); status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, NULL, NULL, NULL); + if (status < 0) + return status; arg = args; @@ -945,7 +949,8 @@ BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags) *flags = COMMAND_LINE_SEPARATOR_COLON; *flags |= COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SIGIL_PLUS_MINUS; } - else + /* Ignore legacy parsing in case there is an error in the command line. */ + else if (old_cli_status >= 0) { if ((old_cli_status == 1) || ((old_cli_count > posix_cli_count) && (old_cli_status != -1))) { @@ -966,12 +971,7 @@ int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* { COMMAND_LINE_ARGUMENT_A* arg; - if (status == COMMAND_LINE_STATUS_PRINT_HELP) - { - freerdp_client_print_command_line_help(argc, argv); - return COMMAND_LINE_STATUS_PRINT_HELP; - } - else if (status == COMMAND_LINE_STATUS_PRINT_VERSION) + if (status == COMMAND_LINE_STATUS_PRINT_VERSION) { freerdp_client_print_version(); return COMMAND_LINE_STATUS_PRINT_VERSION; @@ -1015,6 +1015,11 @@ int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* return COMMAND_LINE_STATUS_PRINT; } + else if (status < 0) + { + freerdp_client_print_command_line_help(argc, argv); + return COMMAND_LINE_STATUS_PRINT_HELP; + } return 0; } @@ -1043,6 +1048,8 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin CommandLineClearArgumentsA(args); status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings, freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter); + if (status < 0) + return status; } @@ -1626,7 +1633,8 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin } CommandLineSwitchDefault(arg) { - + fprintf(stderr, "Unknown argument %s\n", __func__, arg->Name); + return COMMAND_LINE_ERROR; } CommandLineSwitchEnd(arg) diff --git a/client/common/compatibility.c b/client/common/compatibility.c index 048afa599..641bf2f65 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -315,6 +315,7 @@ int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count) detect_status = 0; flags = COMMAND_LINE_SEPARATOR_SPACE; flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH; + flags |= COMMAND_LINE_SIGIL_NOT_ESCAPED; settings = (rdpSettings*) malloc(sizeof(rdpSettings)); ZeroMemory(settings, sizeof(rdpSettings)); @@ -322,6 +323,8 @@ int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count) CommandLineClearArgumentsA(old_args); status = CommandLineParseArgumentsA(argc, (const char**) argv, old_args, flags, settings, freerdp_client_old_command_line_pre_filter, NULL); + if (status < 0) + return status; arg = old_args; @@ -383,16 +386,12 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe flags = COMMAND_LINE_SEPARATOR_SPACE; flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH; flags |= COMMAND_LINE_SIGIL_ENABLE_DISABLE; + flags |= COMMAND_LINE_SIGIL_NOT_ESCAPED; status = CommandLineParseArgumentsA(argc, (const char**) argv, old_args, flags, settings, freerdp_client_old_command_line_pre_filter, freerdp_client_old_command_line_post_filter); - if (status == COMMAND_LINE_STATUS_PRINT_HELP) - { - freerdp_client_print_command_line_help(argc, argv); - return COMMAND_LINE_STATUS_PRINT_HELP; - } - else if (status == COMMAND_LINE_STATUS_PRINT_VERSION) + if (status == COMMAND_LINE_STATUS_PRINT_VERSION) { freerdp_client_print_version(); return COMMAND_LINE_STATUS_PRINT_VERSION; @@ -401,6 +400,15 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe { return COMMAND_LINE_STATUS_PRINT; } + else if (status < 0) + { + if (status != COMMAND_LINE_STATUS_PRINT_HELP) + { + + } + freerdp_client_print_command_line_help(argc, argv); + return COMMAND_LINE_STATUS_PRINT_HELP; + } arg = old_args; diff --git a/winpr/include/winpr/cmdline.h b/winpr/include/winpr/cmdline.h index bc67d4f52..ca7ae7292 100644 --- a/winpr/include/winpr/cmdline.h +++ b/winpr/include/winpr/cmdline.h @@ -53,6 +53,7 @@ #define COMMAND_LINE_SIGIL_DOUBLE_DASH 0x00000008 #define COMMAND_LINE_SIGIL_PLUS_MINUS 0x00000010 #define COMMAND_LINE_SIGIL_ENABLE_DISABLE 0x00000020 +#define COMMAND_LINE_SIGIL_NOT_ESCAPED 0x00000040 #define COMMAND_LINE_SEPARATOR_COLON 0x00000100 #define COMMAND_LINE_SEPARATOR_EQUAL 0x00000200 diff --git a/winpr/libwinpr/utils/cmdline.c b/winpr/libwinpr/utils/cmdline.c index 0c998ea4c..1e6c45079 100644 --- a/winpr/libwinpr/utils/cmdline.c +++ b/winpr/libwinpr/utils/cmdline.c @@ -53,7 +53,8 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* int count; int length; int index; - BOOL match; + BOOL match, found, argument = FALSE; + BOOL notescaped = FALSE; char* sigil; int sigil_length; int sigil_index; @@ -81,12 +82,12 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* for (i = 1; i < argc; i++) { + BOOL escaped = TRUE; index = i; if (preFilter) { count = preFilter(context, i, argc, argv); - if (count < 0) { status = COMMAND_LINE_ERROR; @@ -131,12 +132,21 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* { sigil_length = 0; } + else if (flags & COMMAND_LINE_SIGIL_NOT_ESCAPED) + { + if (notescaped) + return COMMAND_LINE_ERROR; + sigil_length = 0; + escaped = FALSE; + notescaped = TRUE; + } else { - continue; + return COMMAND_LINE_ERROR; } - - if ((sigil_length > 0) || (flags & COMMAND_LINE_SIGIL_NONE)) + + if ((sigil_length > 0) || (flags & COMMAND_LINE_SIGIL_NONE) || + (flags & COMMAND_LINE_SIGIL_NOT_ESCAPED)) { if (length < (sigil_length + 1)) return COMMAND_LINE_ERROR_NO_KEYWORD; @@ -192,6 +202,10 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* value_length = 0; } + if (!escaped) + continue; + + found = FALSE; for (j = 0; options[j].Name != NULL; j++) { match = FALSE; @@ -214,6 +228,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* if (!match) continue; + found = match; options[j].Index = index; if ((flags & COMMAND_LINE_SEPARATOR_SPACE) && ((i + 1) < argc)) @@ -238,7 +253,13 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* value_present = 0; } - if (value_present) + if ((options[j].Flags & COMMAND_LINE_VALUE_REQUIRED) || + (options[j].Flags & COMMAND_LINE_VALUE_OPTIONAL)) + argument = TRUE; + else + argument = FALSE; + + if (value_present && argument) { i++; value_index = 0; @@ -247,6 +268,14 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* value = (char*) &argv[i][value_index]; value_length = (length - value_index); } + else if (!value_present && (options[j].Flags & COMMAND_LINE_VALUE_OPTIONAL)) + { + value_index = 0; + value = NULL; + value_length = 0; + } + else if (!value_present && argument) + return COMMAND_LINE_ERROR; } if (!(flags & COMMAND_LINE_SEPARATOR_SPACE)) @@ -320,6 +349,9 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* else if (options[j].Flags & COMMAND_LINE_PRINT_VERSION) return COMMAND_LINE_STATUS_PRINT_VERSION; } + + if (!found) + return COMMAND_LINE_ERROR_NO_KEYWORD; } }