From 34db67680dd307bf5c60f46b1f723be2c803e32a Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Thu, 8 Jan 2015 10:44:05 -0800 Subject: [PATCH] Ignore user-supplied fd redirections above 2 for builtins Prevents e.g. specifying an fd which corresponds to the history file as the stdin for builtin_source --- exec.cpp | 10 +++++++--- io.h | 8 ++++++-- parse_execution.cpp | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/exec.cpp b/exec.cpp index 18d5313d2..972291804 100644 --- a/exec.cpp +++ b/exec.cpp @@ -366,7 +366,7 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t *out_chain, s } opened_fds.push_back(fd); - out.reset(new io_fd_t(in->fd, fd)); + out.reset(new io_fd_t(in->fd, fd, false)); break; } @@ -867,7 +867,7 @@ void exec_job(parser_t &parser, job_t *j) case INTERNAL_BUILTIN: { - int local_builtin_stdin = 0; + int local_builtin_stdin = STDIN_FILENO; bool close_stdin = false; /* @@ -887,7 +887,11 @@ void exec_job(parser_t &parser, job_t *j) case IO_FD: { CAST_INIT(const io_fd_t *, in_fd, in.get()); - local_builtin_stdin = in_fd->old_fd; + /* Ignore user-supplied fd redirections from an fd other than the standard ones. e.g. in source <&3 don't actually read from fd 3, which is internal to fish. We still respect this redirection in that we pass it on as a block IO to the code that source runs, and therefore this is not an error. Non-user supplied fd redirections come about through transmogrification, and we need to respect those here. */ + if (! in_fd->user_supplied || (in_fd->old_fd >= 0 && in_fd->old_fd < 3)) + { + local_builtin_stdin = in_fd->old_fd; + } break; } case IO_PIPE: diff --git a/io.h b/io.h index 98657e7e5..4ca5f9421 100644 --- a/io.h +++ b/io.h @@ -66,11 +66,15 @@ public: /** fd to redirect specified fd to. For example, in 2>&1, old_fd is 1, and io_data_t::fd is 2 */ const int old_fd; + /** Whether this redirection was supplied by a script. For example, 'cmd <&3' would have user_supplied set to true. But a redirection that comes about through transmogrification would not. */ + const bool user_supplied; + virtual void print() const; - io_fd_t(int f, int old) : + io_fd_t(int f, int old, bool us) : io_data_t(IO_FD, f), - old_fd(old) + old_fd(old), + user_supplied(us) { } }; diff --git a/parse_execution.cpp b/parse_execution.cpp index 749ab805d..c75c135f2 100644 --- a/parse_execution.cpp +++ b/parse_execution.cpp @@ -1083,7 +1083,7 @@ bool parse_execution_context_t::determine_io_chain(const parse_node_t &statement } else { - new_io.reset(new io_fd_t(source_fd, old_fd)); + new_io.reset(new io_fd_t(source_fd, old_fd, true)); } } break;