Skip to content

Commit 2158a1a

Browse files
committed
Trim colon from device names
If output is redirected to name with a colon suffix, test if the unsuffixed name exists as a device and use that, or error.
1 parent 57f199e commit 2158a1a

File tree

1 file changed

+62
-6
lines changed

1 file changed

+62
-6
lines changed

src/command.c

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
364401
static 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

Comments
 (0)