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!)
This commit is contained in:
Fabian Homborg 2021-02-15 17:06:43 +01:00
parent ef5db47cf7
commit c27fb9b802
2 changed files with 13 additions and 4 deletions

View File

@ -62,22 +62,26 @@ maybe_t<int> 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<int> 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"<stdin>" : fn_intern);
fn_intern == intern_static(L"-") ? L"<stdin>" : esc.c_str());
} else {
retval = parser.get_last_status();
}

View File

@ -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