From 7abeba6aeb2de6ab55702524a2c35da1c7da2ee1 Mon Sep 17 00:00:00 2001 From: Euan Date: Tue, 31 Mar 2020 14:50:24 +0100 Subject: [PATCH] #13806 - getApplFreebsd might lose data (#13807) * #13806 - first call sysctl with a null buffer to get the length, then alloc buffer and call again * Use csize_t rather than csize * Suggestions from @Clyybber Co-authored-by: Euan Torano --- lib/pure/os.nim | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index fda482bc3..98143bc1a 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -2791,23 +2791,23 @@ when not weirdTarget and (defined(freebsd) or defined(dragonfly)): const KERN_PROC_PATHNAME = 9 proc getApplFreebsd(): string = - var pathLength = csize_t(MAX_PATH) - result = newString(pathLength) + var pathLength = csize_t(0) var req = [CTL_KERN.cint, KERN_PROC.cint, KERN_PROC_PATHNAME.cint, -1.cint] - while true: - let res = sysctl(addr req[0], 4, cast[pointer](addr result[0]), - addr pathLength, nil, 0) - if res < 0: - let err = osLastError() - if err.int32 == ENOMEM: - result = newString(pathLength) - else: - result.setLen(0) # error! - break - else: - # trim the trailing null byte, as the result is a string not a cstring - result.setLen(pathLength-1) - break + + # first call to get the required length + var res = sysctl(addr req[0], 4, nil, addr pathLength, nil, 0) + + if res < 0: + return "" + + result.setLen(pathLength) + res = sysctl(addr req[0], 4, addr result[0], addr pathLength, nil, 0) + + if res < 0: + return "" + + let realLen = len(cstring(result)) + setLen(result, realLen) when not weirdTarget and (defined(linux) or defined(solaris) or defined(bsd) or defined(aix)): proc getApplAux(procPath: string): string =