From 322ceb7ab4be5b07c3bfa7fc240065916641f8c0 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Thu, 24 Dec 2020 08:53:08 +0100 Subject: [PATCH] builtin realpath: use absolute path also with -s/--no-symlinks The old test needs to be changed because $XDG_DATA_HOME can be relative. Fixes #7574 --- src/builtin_realpath.cpp | 13 ++++++++----- tests/checks/realpath.fish | 15 ++++++++++++--- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/builtin_realpath.cpp b/src/builtin_realpath.cpp index 44739cf3d..1268e4e73 100644 --- a/src/builtin_realpath.cpp +++ b/src/builtin_realpath.cpp @@ -12,6 +12,7 @@ #include "common.h" #include "fallback.h" // IWYU pragma: keep #include "io.h" +#include "wcstringutil.h" #include "wgetopt.h" #include "wutil.h" // IWYU pragma: keep @@ -80,25 +81,27 @@ maybe_t builtin_realpath(parser_t &parser, io_streams_t &streams, wchar_t * return STATUS_INVALID_ARGS; } + const wchar_t *arg = argv[optind]; + if (!opts.no_symlinks) { - if (auto real_path = wrealpath(argv[optind])) { + if (auto real_path = wrealpath(arg)) { streams.out.append(*real_path); } else { if (errno) { // realpath() just couldn't do it. Report the error and make it clear // this is an error from our builtin, not the system's realpath. - streams.err.append_format(L"builtin %ls: %ls: %s\n", cmd, argv[optind], + streams.err.append_format(L"builtin %ls: %ls: %s\n", cmd, arg, std::strerror(errno)); } else { // Who knows. Probably a bug in our wrealpath() implementation. - streams.err.append_format(_(L"builtin %ls: Invalid path: %ls\n"), cmd, - argv[optind]); + streams.err.append_format(_(L"builtin %ls: Invalid arg: %ls\n"), cmd, arg); } return STATUS_CMD_ERROR; } } else { - streams.out.append(normalize_path(argv[optind], /* allow leading double slashes */ false)); + wcstring absolute_arg = string_prefixes_string(L"/", arg) ? arg : wgetcwd() + L"/" + arg; + streams.out.append(normalize_path(absolute_arg, /* allow leading double slashes */ false)); } streams.out.append(L"\n"); diff --git a/tests/checks/realpath.fish b/tests/checks/realpath.fish index 60560865e..8e055c873 100644 --- a/tests/checks/realpath.fish +++ b/tests/checks/realpath.fish @@ -63,8 +63,8 @@ else end # With "-s" the symlink is not resolved. -set -l real_path (builtin realpath -s $XDG_DATA_HOME/fish-symlink) -set -l expected_real_path "$XDG_DATA_HOME/fish-symlink" +set -l real_path (builtin realpath -s $data_home_realpath/fish-symlink) +set -l expected_real_path "$data_home_realpath/fish-symlink" if test "$real_path" = "$expected_real_path" echo "fish-symlink handled correctly" # CHECK: fish-symlink handled correctly @@ -72,7 +72,16 @@ else echo "fish-symlink not handled correctly: $real_path != $expected_real_path" >&2 end -test (builtin realpath -s /usr/bin/../) = "/usr" +set -l real_path (builtin realpath -s .) +set -l expected_real_path (pwd) # Logical working directory. +if test "$real_path" = "$expected_real_path" + echo "relative path correctly handled" + # CHECK: relative path correctly handled +else + echo "relative path not handled correctly: $real_path != $expected_real_path" >&2 +end + +test (builtin realpath -s /usr/bin/../) = /usr or echo builtin realpath -s does not resolve .. or resolves symlink wrong # A nonexistent file relative to a valid symlink to a directory gets converted.