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.
This commit is contained in:
parent
97a5d68adf
commit
4e5631daf3
50
src/file.cc
50
src/file.cc
|
@ -634,10 +634,10 @@ String get_kak_binary_path()
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
#if defined(__linux__) or defined(__CYGWIN__) or defined(__gnu_hurd__)
|
#if defined(__linux__) or defined(__CYGWIN__) or defined(__gnu_hurd__)
|
||||||
ssize_t res = readlink("/proc/self/exe", buffer, 2048);
|
ssize_t res = readlink("/proc/self/exe", buffer, 2048);
|
||||||
if (res == -1 || res >= 2048)
|
if (res != -1 && res < 2048) {
|
||||||
throw runtime_error("unable to get the executable path");
|
buffer[res] = '\0';
|
||||||
buffer[res] = '\0';
|
return buffer;
|
||||||
return buffer;
|
}
|
||||||
#elif defined(__FreeBSD__) or defined(__NetBSD__)
|
#elif defined(__FreeBSD__) or defined(__NetBSD__)
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
|
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};
|
int mib[] = {CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME};
|
||||||
#endif
|
#endif
|
||||||
size_t res = sizeof(buffer);
|
size_t res = sizeof(buffer);
|
||||||
sysctl(mib, 4, buffer, &res, NULL, 0);
|
if (sysctl(mib, 4, buffer, &res, NULL, 0) != -1)
|
||||||
return buffer;
|
return buffer;
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
uint32_t bufsize = 2048;
|
uint32_t bufsize = 2048;
|
||||||
_NSGetExecutablePath(buffer, &bufsize);
|
char* canonical_path = NULL;
|
||||||
char* canonical_path = realpath(buffer, nullptr);
|
if (_NSGetExecutablePath(buffer, &bufsize) != -1)
|
||||||
String path = canonical_path;
|
canonical_path = realpath(buffer, nullptr);
|
||||||
free(canonical_path);
|
if (canonical_path) {
|
||||||
return path;
|
String path = canonical_path;
|
||||||
|
free(canonical_path);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
#elif defined(__HAIKU__)
|
#elif defined(__HAIKU__)
|
||||||
BApplication app("application/x-vnd.kakoune");
|
BApplication app("application/x-vnd.kakoune");
|
||||||
app_info info;
|
app_info info;
|
||||||
status_t status = app.GetAppInfo(&info);
|
if (app.GetAppInfo(&info) == B_OK) {
|
||||||
kak_assert(status == B_OK);
|
BPath path(&info.ref);
|
||||||
BPath path(&info.ref);
|
return path.Path();
|
||||||
return path.Path();
|
}
|
||||||
#elif defined(__DragonFly__)
|
#elif defined(__DragonFly__)
|
||||||
ssize_t res = readlink("/proc/curproc/file", buffer, 2048);
|
ssize_t res = readlink("/proc/curproc/file", buffer, 2048);
|
||||||
if (res == -1 || res >= 2048)
|
if (res != -1 && res < 2048) {
|
||||||
throw runtime_error("unable to get the executable path");
|
buffer[res] = '\0';
|
||||||
buffer[res] = '\0';
|
return buffer;
|
||||||
return buffer;
|
}
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__)
|
||||||
(void)buffer;
|
(void)buffer;
|
||||||
return KAK_BIN_PATH;
|
return KAK_BIN_PATH;
|
||||||
#elif defined(__sun__)
|
#elif defined(__sun__)
|
||||||
ssize_t res = readlink("/proc/self/path/a.out", buffer, 2048);
|
ssize_t res = readlink("/proc/self/path/a.out", buffer, 2048);
|
||||||
if (res == -1 || res >= 2048)
|
if (res != -1 && res < 2048) {
|
||||||
throw runtime_error("unable to get the executable path");
|
buffer[res] = '\0';
|
||||||
buffer[res] = '\0';
|
return buffer;
|
||||||
return buffer;
|
}
|
||||||
#else
|
#else
|
||||||
# error "finding executable path is not implemented on this platform"
|
# error "finding executable path is not implemented on this platform"
|
||||||
#endif
|
#endif
|
||||||
|
throw runtime_error("unable to get the executable path");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user