diff options
| author | Chris Webb <chris@arachsys.com> | 2024-05-12 12:12:58 +0100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2024-05-12 21:59:56 +1000 |
| commit | 4e5631daf3a62bff1d7c4d2e697535ed4ebffcba (patch) | |
| tree | 530a1c0eea3b0169a9ad36f6ee0d96b23fc37a7a | |
| parent | 97a5d68adf48e99ac19dce21b32cecc7de9f0daa (diff) | |
Handle binary path detection errors on non-/proc platforms
On FreeBSD and NetBSD, sysctl() can return -1 when the path is too long,
leaving the buffer unitialised.
On macOS, both _NSGetExecutablePath() and realpath() can fail with
pathological paths or if memory is exhausted.
On Haiku, the kak_assert(status == B_OK) check will be compiled out in
non-debug builds.
Detect all of these cases and error out, reshaping get_kak_binary_path()
to avoid multiple repetitions of the same fatal error message.
| -rw-r--r-- | src/file.cc | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/src/file.cc b/src/file.cc index b9d3212c..ca2d2834 100644 --- a/src/file.cc +++ b/src/file.cc @@ -634,10 +634,10 @@ String get_kak_binary_path() char buffer[2048]; #if defined(__linux__) or defined(__CYGWIN__) or defined(__gnu_hurd__) ssize_t res = readlink("/proc/self/exe", buffer, 2048); - if (res == -1 || res >= 2048) - throw runtime_error("unable to get the executable path"); - buffer[res] = '\0'; - return buffer; + if (res != -1 && res < 2048) { + buffer[res] = '\0'; + return buffer; + } #elif defined(__FreeBSD__) or defined(__NetBSD__) #if defined(__FreeBSD__) int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; @@ -645,40 +645,44 @@ String get_kak_binary_path() int mib[] = {CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME}; #endif size_t res = sizeof(buffer); - sysctl(mib, 4, buffer, &res, NULL, 0); - return buffer; + if (sysctl(mib, 4, buffer, &res, NULL, 0) != -1) + return buffer; #elif defined(__APPLE__) uint32_t bufsize = 2048; - _NSGetExecutablePath(buffer, &bufsize); - char* canonical_path = realpath(buffer, nullptr); - String path = canonical_path; - free(canonical_path); - return path; + char* canonical_path = NULL; + if (_NSGetExecutablePath(buffer, &bufsize) != -1) + canonical_path = realpath(buffer, nullptr); + if (canonical_path) { + String path = canonical_path; + free(canonical_path); + return path; + } #elif defined(__HAIKU__) BApplication app("application/x-vnd.kakoune"); app_info info; - status_t status = app.GetAppInfo(&info); - kak_assert(status == B_OK); - BPath path(&info.ref); - return path.Path(); + if (app.GetAppInfo(&info) == B_OK) { + BPath path(&info.ref); + return path.Path(); + } #elif defined(__DragonFly__) ssize_t res = readlink("/proc/curproc/file", buffer, 2048); - if (res == -1 || res >= 2048) - throw runtime_error("unable to get the executable path"); - buffer[res] = '\0'; - return buffer; + if (res != -1 && res < 2048) { + buffer[res] = '\0'; + return buffer; + } #elif defined(__OpenBSD__) (void)buffer; return KAK_BIN_PATH; #elif defined(__sun__) ssize_t res = readlink("/proc/self/path/a.out", buffer, 2048); - if (res == -1 || res >= 2048) - throw runtime_error("unable to get the executable path"); - buffer[res] = '\0'; - return buffer; + if (res != -1 && res < 2048) { + buffer[res] = '\0'; + return buffer; + } #else # error "finding executable path is not implemented on this platform" #endif + throw runtime_error("unable to get the executable path"); } } |
