From c27fb9b80200887c59e359a8f546f0ccf7cebcbe Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Mon, 15 Feb 2021 17:06:43 +0100 Subject: [PATCH] source: Escape filenames in errors Otherwise this would look weird if you had, say, a tab in there. See #7716. (note that this doesn't handle e.g. zero-width-joiners, because those aren't currently escaped. we might want to add an escape mode for unprintable characters, but for combining codepoints that's tricky!) --- src/builtin_source.cpp | 13 +++++++++---- tests/checks/eval.fish | 4 ++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/builtin_source.cpp b/src/builtin_source.cpp index 8a3430dfc..0fc73326a 100644 --- a/src/builtin_source.cpp +++ b/src/builtin_source.cpp @@ -62,22 +62,26 @@ maybe_t builtin_source(parser_t &parser, io_streams_t &streams, wchar_t **a } else { opened_fd = autoclose_fd_t(wopen_cloexec(argv[optind], O_RDONLY)); if (!opened_fd.valid()) { + wcstring esc = escape_string(argv[optind], ESCAPE_ALL); streams.err.append_format(_(L"%ls: Error encountered while sourcing file '%ls':\n"), - cmd, argv[optind]); + cmd, esc.c_str()); builtin_wperror(cmd, streams); return STATUS_CMD_ERROR; } fd = opened_fd.fd(); if (fstat(fd, &buf) == -1) { + wcstring esc = escape_string(argv[optind], ESCAPE_ALL); streams.err.append_format(_(L"%ls: Error encountered while sourcing file '%ls':\n"), - cmd, argv[optind]); + cmd, esc.c_str()); builtin_wperror(L"source", streams); return STATUS_CMD_ERROR; } if (!S_ISREG(buf.st_mode)) { - streams.err.append_format(_(L"%ls: '%ls' is not a file\n"), cmd, argv[optind]); + wcstring esc = escape_string(argv[optind], ESCAPE_ALL); + streams.err.append_format(_(L"%ls: '%ls' is not a file\n"), + cmd, esc.c_str()); return STATUS_CMD_ERROR; } @@ -100,8 +104,9 @@ maybe_t builtin_source(parser_t &parser, io_streams_t &streams, wchar_t **a parser.pop_block(sb); if (retval != STATUS_CMD_OK) { + wcstring esc = escape_string(fn_intern, ESCAPE_ALL); streams.err.append_format(_(L"%ls: Error while reading file '%ls'\n"), cmd, - fn_intern == intern_static(L"-") ? L"" : fn_intern); + fn_intern == intern_static(L"-") ? L"" : esc.c_str()); } else { retval = parser.get_last_status(); } diff --git a/tests/checks/eval.fish b/tests/checks/eval.fish index e484f0aed..db43ebd18 100644 --- a/tests/checks/eval.fish +++ b/tests/checks/eval.fish @@ -56,3 +56,7 @@ false eval "begin; end;" echo empty block eval: $status # 0 # CHECK: empty block eval: 0 + +source /banana/\t/foo +# CHECKERR: source: Error encountered while sourcing file '/banana/\t/foo': +# CHECKERR: source: No such file or directory