@@ -361,6 +361,43 @@ static void conv_unix_path_to_ms_dos(char *path)
361361 }
362362 }
363363
364+ /* check for form "NUL:"
365+ * returns:
366+ * -1 for invalid name (maybe has colon suffix, but doesn't resolve to a device)
367+ * 0 for a name without colon
368+ * 1 for is a device name with colon at position (*colon) */
369+ static int is_device_with_colon (const char * name , int * colon )
370+ {
371+ int ret = -1 ;
372+ int len ;
373+ char * s , * pcolon ;
374+ finddata_t ff ;
375+
376+ pcolon = strchr (name , ':' );
377+ if (!pcolon ) // Plain device name or file
378+ return 0 ;
379+
380+ len = strlen (name );
381+ if (& name [len - 1 ] != pcolon ) // More than one colon, or it's not the last character
382+ return -1 ;
383+
384+ if (len < 3 ) // Single ':' or probable drive '?:'
385+ return -1 ;
386+
387+ s = strndup (name , len - 1 );
388+ if (!s )
389+ return -1 ;
390+
391+ if (findfirst_f (s , & ff , FA_DIREC + FA_RDONLY + FA_ARCH + FA_SYSTEM + FA_HIDDEN , NULL ) == 0 &&
392+ ff .ff_attrib == _A_DEVICE ) {
393+ * colon = len - 1 ;
394+ ret = 1 ;
395+ }
396+
397+ free (s );
398+ return ret ;
399+ }
400+
364401static int is_drive_spec (char * s ) // check for form "A:"
365402 {
366403 if (!isalpha (s [0 ]))
@@ -4568,13 +4605,31 @@ static void exec_cmd(int call)
45684605 }
45694606 else // open the pipe file
45704607 {
4571- if (pipe_file_redir_count [STDIN_INDEX ] > 0 )
4608+ int colon , rc ;
4609+
4610+ if (pipe_file_redir_count [STDIN_INDEX ] > 0 ) {
4611+ rc = is_device_with_colon (pipe_file [STDIN_INDEX ], & colon );
4612+ if (rc == -1 ) {
4613+ cprintf ("Invalid standard input device name '%s'\r\n" , pipe_file [STDIN_INDEX ]);
4614+ goto Exit ;
4615+ } else if (rc == 1 ) {
4616+ pipe_file [STDIN_INDEX ][colon ] = '\0' ;
4617+ }
45724618 pipe_fno [STDIN_INDEX ] = open (pipe_file [STDIN_INDEX ], O_TEXT |O_RDONLY , S_IRUSR );
4619+ }
45734620
4574- if (pipe_file_redir_count [STDOUT_INDEX ] > 1 )
4575- pipe_fno [STDOUT_INDEX ] = open (pipe_file [STDOUT_INDEX ], O_BINARY |O_WRONLY |O_APPEND |O_CREAT , S_IRUSR | S_IWUSR ); // open for append
4576- else if (pipe_file_redir_count [STDOUT_INDEX ] == 1 )
4577- pipe_fno [STDOUT_INDEX ] = open (pipe_file [STDOUT_INDEX ], O_BINARY |O_WRONLY |O_TRUNC |O_CREAT , S_IRUSR | S_IWUSR ); // open as new file
4621+ if (pipe_file_redir_count [STDOUT_INDEX ] > 0 ) {
4622+ rc = is_device_with_colon (pipe_file [STDOUT_INDEX ], & colon );
4623+ if (rc == -1 ) {
4624+ cprintf ("Invalid standard output device name '%s'\r\n" , pipe_file [STDOUT_INDEX ]);
4625+ goto Exit ;
4626+ } else if (rc == 1 ) {
4627+ pipe_file [STDOUT_INDEX ][colon ] = '\0' ;
4628+ }
4629+ if (pipe_file_redir_count [STDOUT_INDEX ] == 1 )
4630+ pipe_fno [STDOUT_INDEX ] = open (pipe_file [STDOUT_INDEX ], O_BINARY |O_WRONLY |O_TRUNC |O_CREAT , S_IRUSR | S_IWUSR ); // open as new file
4631+ else
4632+ pipe_fno [STDOUT_INDEX ] = open (pipe_file [STDOUT_INDEX ], O_BINARY |O_WRONLY |O_APPEND |O_CREAT , S_IRUSR | S_IWUSR ); // open for append
45784633
45794634 /* check for error
45804635 if (pipe_fno[pipe_index] < 0 ||
@@ -4589,6 +4644,7 @@ static void exec_cmd(int call)
45894644 goto Exit;
45904645 } */
45914646 }
4647+ }
45924648
45934649 for (pipe_index = 0 ; pipe_index < 2 ; pipe_index ++ )
45944650 {
@@ -4666,7 +4722,7 @@ static void exec_cmd(int call)
46664722 exec_cmd (true);
46674723 }
46684724
4669- /* Exit: */
4725+ Exit :
46704726 cmd_line [0 ] = '\0' ;
46714727 if (redir_result [STDIN_INDEX ] != -1 ) {
46724728 dup2 (old_std_fno [STDIN_INDEX ], STDIN_INDEX );
0 commit comments