summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Webb <chris@arachsys.com>2024-05-12 12:12:58 +0100
committerMaxime Coste <mawww@kakoune.org>2024-05-12 21:59:56 +1000
commit4e5631daf3a62bff1d7c4d2e697535ed4ebffcba (patch)
tree530a1c0eea3b0169a9ad36f6ee0d96b23fc37a7a
parent97a5d68adf48e99ac19dce21b32cecc7de9f0daa (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.cc50
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");
}
}