@@ -13,7 +13,7 @@ pub const env_var_name = "TURBOCRYPT_KEY_FILE";
1313///
1414/// Returns an owned slice that the caller must free.
1515/// Returns null if key should be loaded from config.
16- pub fn resolveKeyPath (allocator : std.mem.Allocator , optional_cli_path : ? []const u8 ) ! ? []const u8 {
16+ pub fn resolveKeyPath (allocator : std.mem.Allocator , optional_cli_path : ? []const u8 , environ_map : * const std.process.Environ.Map ) ! ? []const u8 {
1717 // Priority 1: CLI argument
1818 if (optional_cli_path ) | cli_path | {
1919 if (cli_path .len > 0 ) {
@@ -22,13 +22,10 @@ pub fn resolveKeyPath(allocator: std.mem.Allocator, optional_cli_path: ?[]const
2222 }
2323
2424 // Priority 2: Environment variable
25- if (std . process . getEnvVarOwned ( allocator , env_var_name )) | env_path | {
25+ if (environ_map . get ( env_var_name )) | env_path | {
2626 if (env_path .len > 0 ) {
27- return env_path ; // Already owned
27+ return try allocator . dupe ( u8 , env_path );
2828 }
29- allocator .free (env_path );
30- } else | _ | {
31- // Environment variable not set or error reading it - continue to next priority
3229 }
3330
3431 // Priority 3: Config file - return null to signal key should be loaded from config
@@ -41,16 +38,16 @@ pub fn resolveKeyPath(allocator: std.mem.Allocator, optional_cli_path: ?[]const
4138/// 3. Config file (use stored key)
4239///
4340/// Returns error.KeyNotFound if no key is configured.
44- pub fn resolveKey (allocator : std.mem.Allocator , optional_cli_path : ? []const u8 , password_opt : ? []const u8 , io : std.Io ) ! [16 ]u8 {
45- const key_path = try resolveKeyPath (allocator , optional_cli_path );
41+ pub fn resolveKey (allocator : std.mem.Allocator , optional_cli_path : ? []const u8 , password_opt : ? []const u8 , io : std.Io , environ_map : * const std.process.Environ.Map ) ! [16 ]u8 {
42+ const key_path = try resolveKeyPath (allocator , optional_cli_path , environ_map );
4643
4744 if (key_path ) | path | {
4845 // Load from file
4946 defer allocator .free (path );
5047 return try keygen .readKeyFile (path , password_opt , io );
5148 } else {
5249 // Load from config
53- var cfg = try config .load (allocator , io );
50+ var cfg = try config .load (allocator , io , environ_map );
5451 defer cfg .deinit (allocator );
5552
5653 if (cfg .key ) | key_data | {
@@ -86,17 +83,17 @@ pub fn resolveKey(allocator: std.mem.Allocator, optional_cli_path: ?[]const u8,
8683}
8784
8885/// Get the full path to the config file
89- pub fn getConfigFilePath (allocator : std.mem.Allocator ) ! []const u8 {
90- return try config .getConfigFilePath (allocator );
86+ pub fn getConfigFilePath (allocator : std.mem.Allocator , environ_map : * const std.process.Environ.Map ) ! []const u8 {
87+ return try config .getConfigFilePath (allocator , environ_map );
9188}
9289
9390/// Set the default key in the config file
9491/// key_data should be in the same format as key files:
9592/// - 16 bytes: plain key
9693/// - 21 bytes: password-protected (1 flag byte + 16 XOR'd bytes + 4 checksum bytes)
97- pub fn setDefaultKey (allocator : std.mem.Allocator , key_data : []const u8 , io : std.Io ) ! void {
94+ pub fn setDefaultKey (allocator : std.mem.Allocator , key_data : []const u8 , io : std.Io , environ_map : * const std.process.Environ.Map ) ! void {
9895 // Load existing config
99- var cfg = try config .load (allocator , io );
96+ var cfg = try config .load (allocator , io , environ_map );
10097 defer cfg .deinit (allocator );
10198
10299 // Free old key if exists
@@ -108,11 +105,11 @@ pub fn setDefaultKey(allocator: std.mem.Allocator, key_data: []const u8, io: std
108105 cfg .key = try allocator .dupe (u8 , key_data );
109106
110107 // Save config
111- try config .save (cfg , allocator , io );
108+ try config .save (cfg , allocator , io , environ_map );
112109}
113110
114111/// Get information about where the key would be loaded from (for user feedback)
115- pub fn describeKeySource (allocator : std.mem.Allocator , optional_cli_path : ? []const u8 , io : std.Io ) ! []const u8 {
112+ pub fn describeKeySource (allocator : std.mem.Allocator , optional_cli_path : ? []const u8 , io : std.Io , environ_map : * const std.process.Environ.Map ) ! []const u8 {
116113 // Check CLI argument
117114 if (optional_cli_path ) | cli_path | {
118115 if (cli_path .len > 0 ) {
@@ -121,18 +118,17 @@ pub fn describeKeySource(allocator: std.mem.Allocator, optional_cli_path: ?[]con
121118 }
122119
123120 // Check environment variable
124- if (std .process .getEnvVarOwned (allocator , env_var_name )) | env_path | {
125- defer allocator .free (env_path );
121+ if (environ_map .get (env_var_name )) | env_path | {
126122 if (env_path .len > 0 ) {
127123 return try std .fmt .allocPrint (allocator , "Environment variable {s}: {s}" , .{ env_var_name , env_path });
128124 }
129- } else | _ | {}
125+ }
130126
131127 // Check config file
132- const config_path = try config .getConfigFilePath (allocator );
128+ const config_path = try config .getConfigFilePath (allocator , environ_map );
133129 defer allocator .free (config_path );
134130
135- var cfg = config .load (allocator , io ) catch {
131+ var cfg = config .load (allocator , io , environ_map ) catch {
136132 return try allocator .dupe (u8 , "No key configured" );
137133 };
138134 defer cfg .deinit (allocator );
@@ -151,16 +147,20 @@ pub fn describeKeySource(allocator: std.mem.Allocator, optional_cli_path: ?[]con
151147
152148test "resolveKeyPath - CLI argument takes priority" {
153149 const allocator = std .testing .allocator ;
150+ var environ_map = std .process .Environ .Map .init (allocator );
151+ defer environ_map .deinit ();
154152
155- const result = try resolveKeyPath (allocator , "/path/from/cli" );
153+ const result = try resolveKeyPath (allocator , "/path/from/cli" , & environ_map );
156154 defer if (result ) | path | allocator .free (path );
157155
158156 try std .testing .expectEqualStrings ("/path/from/cli" , result .? );
159157}
160158
161159test "resolveKeyPath - returns null when no path configured" {
162160 const allocator = std .testing .allocator ;
161+ var environ_map = std .process .Environ .Map .init (allocator );
162+ defer environ_map .deinit ();
163163
164- const result = try resolveKeyPath (allocator , null );
164+ const result = try resolveKeyPath (allocator , null , & environ_map );
165165 try std .testing .expect (result == null );
166166}
0 commit comments