summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorEuan <euantorano@users.noreply.github.com>2020-03-31 14:50:24 +0100
committerGitHub <noreply@github.com>2020-03-31 15:50:24 +0200
commit7abeba6aeb2de6ab55702524a2c35da1c7da2ee1 (patch)
treede3e81a833421f784d422a45c2adab03d3aea99f
parent5621ff6d097b07bf39b3e05120068c838812ab69 (diff)
downloadNim-7abeba6aeb2de6ab55702524a2c35da1c7da2ee1.tar.gz
#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 <euan.torano@bluesky-wireless.co.uk>
-rw-r--r--lib/pure/os.nim32
1 files 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 =