╭ changed ─────────╮ │src/ssh_helper.zig│ ╰──────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 84 } │ │ 85 │ │ 86 const original_command = environ_map.get("SSH_ORIGINAL_COMMAND") orelse return error.InvalidSshCommand; │ │ 87 - var tokens = try parseShellWords(allocator, original_command); │ │ 88 - defer { │ │ 89 - for (tokens.items) |token| allocator.free(token); │ │ 90 - tokens.deinit(allocator); │ │ 91 - } │ │ 92 - if (tokens.items.len < 2) return error.InvalidSshCommand; │ │ 87 + var tokens = try std.process.Args.IteratorGeneral(.{ .single_quotes = true }).init(allocator, original_command);│ │ 88 + defer tokens.deinit(); │ │ 89 + │ │ 90 + const service_name = tokens.next() orelse return error.InvalidSshCommand; │ │ 91 + const dir = tokens.next() orelse return error.InvalidSshCommand; │ │ 92 │ │ 93 return .{ │ │ 95 - .service = try parseService(tokens.items[0]), │ │ 96 - .dir = try allocator.dupe(u8, tokens.items[1]), │ │ 94 + .service = try parseService(service_name), │ │ 95 + .dir = try allocator.dupe(u8, dir), │ │ 96 }; │ │ 98 -} │ │ 99 - │ │100 -fn parseShellWords(allocator: std.mem.Allocator, command: []const u8) !std.ArrayList([]const u8) { │ │101 - var tokens: std.ArrayList([]const u8) = .empty; │ │102 - errdefer { │ │103 - for (tokens.items) |token| allocator.free(token); │ │104 - tokens.deinit(allocator); │ │105 - } │ │106 - │ │107 - var current: std.ArrayList(u8) = .empty; │ │108 - defer current.deinit(allocator); │ │109 - │ │110 - var quote: ?u8 = null; │ │111 - var escaping = false; │ │112 - var in_token = false; │ │113 - │ │114 - for (command) |c| { │ │115 - if (escaping) { │ │116 - try current.append(allocator, c); │ │117 - escaping = false; │ │118 - in_token = true; │ │119 - continue; │ │120 - } │ │121 - │ │122 - if (c == '\\' and quote != '\'') { │ │123 - escaping = true; │ │124 - in_token = true; │ │125 - continue; │ │126 - } │ │127 - │ │128 - if (quote) |q| { │ │129 - if (c == q) { │ │130 - quote = null; │ │131 - } else { │ │132 - try current.append(allocator, c); │ │133 - } │ │134 - in_token = true; │ │135 - continue; │ │136 - } │ │137 - │ │138 - if (c == '\'' or c == '"') { │ │139 - quote = c; │ │140 - in_token = true; │ │141 - continue; │ │142 - } │ │143 - │ │144 - if (std.ascii.isWhitespace(c)) { │ │145 - if (in_token) { │ │146 - try tokens.append(allocator, try current.toOwnedSlice(allocator)); │ │147 - current.clearRetainingCapacity(); │ │148 - in_token = false; │ │149 - } │ │150 - continue; │ │151 - } │ │152 - │ │153 - try current.append(allocator, c); │ │154 - in_token = true; │ │155 - } │ │156 - │ │157 - if (escaping or quote != null) return error.InvalidSshCommand; │ │158 - if (in_token) { │ │159 - try tokens.append(allocator, try current.toOwnedSlice(allocator)); │ │160 - } │ │161 - │ │162 - return tokens; │ │ 97 } │ │ 98 │ │ 99 fn parseService(value: []const u8) !Service { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯