@@ -82,7 +82,7 @@ static int SDLCALL process_testArguments(void *arg)
82
82
"" ,
83
83
" " ,
84
84
"a b c" ,
85
- "a\tb\tc\t" ,
85
+ "a\tb\tc\t\v\r\n " ,
86
86
"\"a b\" c" ,
87
87
"'a' 'b' 'c'" ,
88
88
"%d%%%s" ,
@@ -965,6 +965,165 @@ static int process_testFileRedirection(void *arg)
965
965
return TEST_COMPLETED ;
966
966
}
967
967
968
+ static int process_testWindowsCmdline (void * arg )
969
+ {
970
+ TestProcessData * data = (TestProcessData * )arg ;
971
+ const char * process_args [] = {
972
+ data -> childprocess_path ,
973
+ "--print-arguments" ,
974
+ "--" ,
975
+ "" ,
976
+ " " ,
977
+ "a b c" ,
978
+ "a\tb\tc\t" ,
979
+ "\"a b\" c" ,
980
+ "'a' 'b' 'c'" ,
981
+ "%d%%%s" ,
982
+ "\\t\\c" ,
983
+ "evil\\" ,
984
+ "a\\b\"c\\" ,
985
+ "\"\\^&|<>%" , /* characters with a special meaning */
986
+ NULL
987
+ };
988
+ /* this will have the same result as process_args, but escaped in a different way */
989
+ const char * process_cmdline_template =
990
+ "%s "
991
+ "--print-arguments "
992
+ "-- "
993
+ "\"\" "
994
+ "\" \" "
995
+ "a\" \"b\" \"c\t" /* using tab as delimiter */
996
+ "\"a\tb\tc\t\" "
997
+ "\"\"\"\"a b\"\"\" c\" "
998
+ "\"'a' 'b' 'c'\" "
999
+ "%%d%%%%%%s " /* will be passed to sprintf */
1000
+ "\\t\\c "
1001
+ "evil\\ "
1002
+ "a\\b\"\\\"\"c\\ "
1003
+ "\\\"\\^&|<>%%" ;
1004
+ char process_cmdline [65535 ];
1005
+ SDL_PropertiesID props ;
1006
+ SDL_Process * process = NULL ;
1007
+ char * buffer ;
1008
+ int exit_code ;
1009
+ int i ;
1010
+ size_t total_read = 0 ;
1011
+
1012
+ #ifndef SDL_PLATFORM_WINDOWS
1013
+ SDLTest_AssertPass ("SDL_PROP_PROCESS_CREATE_CMDLINE_STRING only works on Windows" );
1014
+ return TEST_SKIPPED ;
1015
+ #endif
1016
+
1017
+ props = SDL_CreateProperties ();
1018
+ SDLTest_AssertCheck (props != 0 , "SDL_CreateProperties()" );
1019
+ if (!props ) {
1020
+ goto failed ;
1021
+ }
1022
+ SDL_SetNumberProperty (props , SDL_PROP_PROCESS_CREATE_STDIN_NUMBER , SDL_PROCESS_STDIO_APP );
1023
+ SDL_SetNumberProperty (props , SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER , SDL_PROCESS_STDIO_APP );
1024
+ SDL_SetBooleanProperty (props , SDL_PROP_PROCESS_CREATE_STDERR_TO_STDOUT_BOOLEAN , true);
1025
+
1026
+ process = SDL_CreateProcessWithProperties (props );
1027
+ SDLTest_AssertCheck (process == NULL , "SDL_CreateProcessWithProperties() should fail" );
1028
+
1029
+ SDL_snprintf (process_cmdline , SDL_arraysize (process_cmdline ), process_cmdline_template , data -> childprocess_path );
1030
+ SDL_SetStringProperty (props , SDL_PROP_PROCESS_CREATE_CMDLINE_STRING , process_cmdline );
1031
+
1032
+ process = SDL_CreateProcessWithProperties (props );
1033
+ SDLTest_AssertCheck (process != NULL , "SDL_CreateProcessWithProperties()" );
1034
+ if (!process ) {
1035
+ goto failed ;
1036
+ }
1037
+
1038
+ exit_code = 0xdeadbeef ;
1039
+ buffer = (char * )SDL_ReadProcess (process , & total_read , & exit_code );
1040
+ SDLTest_AssertCheck (buffer != NULL , "SDL_ReadProcess()" );
1041
+ SDLTest_AssertCheck (exit_code == 0 , "Exit code should be 0, is %d" , exit_code );
1042
+ if (!buffer ) {
1043
+ goto failed ;
1044
+ }
1045
+ SDLTest_LogEscapedString ("stdout of process: " , buffer , total_read );
1046
+
1047
+ for (i = 3 ; process_args [i ]; i ++ ) {
1048
+ char line [64 ];
1049
+ SDL_snprintf (line , sizeof (line ), "|%d=%s|" , i - 3 , process_args [i ]);
1050
+ SDLTest_AssertCheck (!!SDL_strstr (buffer , line ), "Check %s is in output" , line );
1051
+ }
1052
+ SDL_free (buffer );
1053
+
1054
+ SDLTest_AssertPass ("About to destroy process" );
1055
+ SDL_DestroyProcess (process );
1056
+
1057
+ return TEST_COMPLETED ;
1058
+
1059
+ failed :
1060
+ SDL_DestroyProcess (process );
1061
+ return TEST_ABORTED ;
1062
+ }
1063
+
1064
+ static int process_testWindowsCmdlinePrecedence (void * arg )
1065
+ {
1066
+ TestProcessData * data = (TestProcessData * )arg ;
1067
+ const char * process_args [] = {
1068
+ data -> childprocess_path ,
1069
+ "--print-arguments" ,
1070
+ "--" ,
1071
+ "argument 1" ,
1072
+ NULL
1073
+ };
1074
+ const char * process_cmdline_template = "%s --print-arguments -- \"argument 2\"" ;
1075
+ char process_cmdline [65535 ];
1076
+ SDL_PropertiesID props ;
1077
+ SDL_Process * process = NULL ;
1078
+ char * buffer ;
1079
+ int exit_code ;
1080
+ size_t total_read = 0 ;
1081
+
1082
+ #ifndef SDL_PLATFORM_WINDOWS
1083
+ SDLTest_AssertPass ("SDL_PROP_PROCESS_CREATE_CMDLINE_STRING only works on Windows" );
1084
+ return TEST_SKIPPED ;
1085
+ #endif
1086
+
1087
+ props = SDL_CreateProperties ();
1088
+ SDLTest_AssertCheck (props != 0 , "SDL_CreateProperties()" );
1089
+ if (!props ) {
1090
+ goto failed ;
1091
+ }
1092
+
1093
+ SDL_snprintf (process_cmdline , SDL_arraysize (process_cmdline ), process_cmdline_template , data -> childprocess_path );
1094
+ SDL_SetPointerProperty (props , SDL_PROP_PROCESS_CREATE_ARGS_POINTER , (void * )process_args );
1095
+ SDL_SetStringProperty (props , SDL_PROP_PROCESS_CREATE_CMDLINE_STRING , (const char * )process_cmdline );
1096
+ SDL_SetNumberProperty (props , SDL_PROP_PROCESS_CREATE_STDIN_NUMBER , SDL_PROCESS_STDIO_APP );
1097
+ SDL_SetNumberProperty (props , SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER , SDL_PROCESS_STDIO_APP );
1098
+ SDL_SetBooleanProperty (props , SDL_PROP_PROCESS_CREATE_STDERR_TO_STDOUT_BOOLEAN , true);
1099
+
1100
+ process = SDL_CreateProcessWithProperties (props );
1101
+ SDLTest_AssertCheck (process != NULL , "SDL_CreateProcessWithProperties()" );
1102
+ if (!process ) {
1103
+ goto failed ;
1104
+ }
1105
+
1106
+ exit_code = 0xdeadbeef ;
1107
+ buffer = (char * )SDL_ReadProcess (process , & total_read , & exit_code );
1108
+ SDLTest_AssertCheck (buffer != NULL , "SDL_ReadProcess()" );
1109
+ SDLTest_AssertCheck (exit_code == 0 , "Exit code should be 0, is %d" , exit_code );
1110
+ if (!buffer ) {
1111
+ goto failed ;
1112
+ }
1113
+ SDLTest_LogEscapedString ("stdout of process: " , buffer , total_read );
1114
+ SDLTest_AssertCheck (!!SDL_strstr (buffer , "|0=argument 2|" ), "Check |0=argument 2| is printed" );
1115
+ SDL_free (buffer );
1116
+
1117
+ SDLTest_AssertPass ("About to destroy process" );
1118
+ SDL_DestroyProcess (process );
1119
+
1120
+ return TEST_COMPLETED ;
1121
+
1122
+ failed :
1123
+ SDL_DestroyProcess (process );
1124
+ return TEST_ABORTED ;
1125
+ }
1126
+
968
1127
static const SDLTest_TestCaseReference processTestArguments = {
969
1128
process_testArguments , "process_testArguments" , "Test passing arguments to child process" , TEST_ENABLED
970
1129
};
@@ -1017,6 +1176,14 @@ static const SDLTest_TestCaseReference processTestFileRedirection = {
1017
1176
process_testFileRedirection , "process_testFileRedirection" , "Test redirection from/to files" , TEST_ENABLED
1018
1177
};
1019
1178
1179
+ static const SDLTest_TestCaseReference processTestWindowsCmdline = {
1180
+ process_testWindowsCmdline , "process_testWindowsCmdline" , "Test passing cmdline directly to CreateProcess" , TEST_ENABLED
1181
+ };
1182
+
1183
+ static const SDLTest_TestCaseReference processTestWindowsCmdlinePrecedence = {
1184
+ process_testWindowsCmdlinePrecedence , "process_testWindowsCmdlinePrecedence" , "Test SDL_PROP_PROCESS_CREATE_CMDLINE_STRING precedence over SDL_PROP_PROCESS_CREATE_ARGS_POINTER" , TEST_ENABLED
1185
+ };
1186
+
1020
1187
static const SDLTest_TestCaseReference * processTests [] = {
1021
1188
& processTestArguments ,
1022
1189
& processTestExitCode ,
@@ -1031,6 +1198,8 @@ static const SDLTest_TestCaseReference *processTests[] = {
1031
1198
& processTestNonExistingExecutable ,
1032
1199
& processTestBatBadButVulnerability ,
1033
1200
& processTestFileRedirection ,
1201
+ & processTestWindowsCmdline ,
1202
+ & processTestWindowsCmdlinePrecedence ,
1034
1203
NULL
1035
1204
};
1036
1205
0 commit comments