authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2020-12-27 13:00:35+01:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2020-12-27 14:23:59+01:00
log8000262e07d00b996dfcd07ab6c26c5db28f42d9
tree035114f6f29439cf082f4d4f09443a34b5e1b6d6
parent4d1096976aa835becac4554e99f7a92117c380f1
signaturelock-open Commit is signed but in an unrecognized format.

std: clean up sentinel handling for argv/environ


2 files changed, 13 insertions(+), 30 deletions(-)

lib/std/child_process.zig+10-20
...@@ -390,15 +390,8 @@ pub const ChildProcess = struct {...@@ -390,15 +390,8 @@ pub const ChildProcess = struct {
390 // can fail between fork() and execve().390 // can fail between fork() and execve().
391 // Therefore, we do all the allocation for the execve() before the fork().391 // Therefore, we do all the allocation for the execve() before the fork().
392 // This means we must do the null-termination of argv and env vars here.392 // This means we must do the null-termination of argv and env vars here.
393 const argv_buf = try arena.alloc(?[*:0]u8, self.argv.len + 1);393 const argv_buf = try arena.allocSentinel(?[*:0]u8, self.argv.len, null);
394 for (self.argv) |arg, i| {394 for (self.argv) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;
395 const arg_buf = try arena.alloc(u8, arg.len + 1);
396 @memcpy(arg_buf.ptr, arg.ptr, arg.len);
397 arg_buf[arg.len] = 0;
398 argv_buf[i] = arg_buf[0..arg.len :0].ptr;
399 }
400 argv_buf[self.argv.len] = null;
401 const argv_ptr = argv_buf[0..self.argv.len :null].ptr;
402395
403 const envp = m: {396 const envp = m: {
404 if (self.env_map) |env_map| {397 if (self.env_map) |env_map| {
...@@ -465,8 +458,8 @@ pub const ChildProcess = struct {...@@ -465,8 +458,8 @@ pub const ChildProcess = struct {
465 }458 }
466459
467 const err = switch (self.expand_arg0) {460 const err = switch (self.expand_arg0) {
468 .expand => os.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_ptr, envp),461 .expand => os.execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
469 .no_expand => os.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_ptr, envp),462 .no_expand => os.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp),
470 };463 };
471 forkChildErrReport(err_pipe[1], err);464 forkChildErrReport(err_pipe[1], err);
472 }465 }
...@@ -913,23 +906,20 @@ pub fn createWindowsEnvBlock(allocator: *mem.Allocator, env_map: *const BufMap)...@@ -913,23 +906,20 @@ pub fn createWindowsEnvBlock(allocator: *mem.Allocator, env_map: *const BufMap)
913906
914pub fn createNullDelimitedEnvMap(arena: *mem.Allocator, env_map: *const std.BufMap) ![:null]?[*:0]u8 {907pub fn createNullDelimitedEnvMap(arena: *mem.Allocator, env_map: *const std.BufMap) ![:null]?[*:0]u8 {
915 const envp_count = env_map.count();908 const envp_count = env_map.count();
916 const envp_buf = try arena.alloc(?[*:0]u8, envp_count + 1);909 const envp_buf = try arena.allocSentinel(?[*:0]u8, envp_count, null);
917 mem.set(?[*:0]u8, envp_buf, null);
918 {910 {
919 var it = env_map.iterator();911 var it = env_map.iterator();
920 var i: usize = 0;912 var i: usize = 0;
921 while (it.next()) |pair| : (i += 1) {913 while (it.next()) |pair| : (i += 1) {
922 const env_buf = try arena.alloc(u8, pair.key.len + pair.value.len + 2);914 const env_buf = try arena.allocSentinel(u8, pair.key.len + pair.value.len + 1, 0);
923 @memcpy(env_buf.ptr, pair.key.ptr, pair.key.len);915 mem.copy(u8, env_buf, pair.key);
924 env_buf[pair.key.len] = '=';916 env_buf[pair.key.len] = '=';
925 @memcpy(env_buf.ptr + pair.key.len + 1, pair.value.ptr, pair.value.len);917 mem.copy(u8, env_buf[pair.key.len + 1 ..], pair.value);
926 const len = env_buf.len - 1;918 envp_buf[i] = env_buf.ptr;
927 env_buf[len] = 0;
928 envp_buf[i] = env_buf[0..len :0].ptr;
929 }919 }
930 assert(i == envp_count);920 assert(i == envp_count);
931 }921 }
932 return envp_buf[0..envp_count :null];922 return envp_buf;
933}923}
934924
935test "createNullDelimitedEnvMap" {925test "createNullDelimitedEnvMap" {
lib/std/process.zig+3-10
...@@ -816,15 +816,8 @@ pub fn execve(...@@ -816,15 +816,8 @@ pub fn execve(
816 defer arena_allocator.deinit();816 defer arena_allocator.deinit();
817 const arena = &arena_allocator.allocator;817 const arena = &arena_allocator.allocator;
818818
819 const argv_buf = try arena.alloc(?[*:0]u8, argv.len + 1);819 const argv_buf = try arena.allocSentinel(?[*:0]u8, argv.len, null);
820 for (argv) |arg, i| {820 for (argv) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;
821 const arg_buf = try arena.alloc(u8, arg.len + 1);
822 @memcpy(arg_buf.ptr, arg.ptr, arg.len);
823 arg_buf[arg.len] = 0;
824 argv_buf[i] = arg_buf[0..arg.len :0].ptr;
825 }
826 argv_buf[argv.len] = null;
827 const argv_ptr = argv_buf[0..argv.len :null].ptr;
828821
829 const envp = m: {822 const envp = m: {
830 if (env_map) |m| {823 if (env_map) |m| {
...@@ -842,5 +835,5 @@ pub fn execve(...@@ -842,5 +835,5 @@ pub fn execve(
842 }835 }
843 };836 };
844837
845 return os.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_ptr, envp);838 return os.execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_buf.ptr, envp);
846}839}