@@ -100,6 +100,7 @@ pub struct Command {
100
100
uid : Option < uid_t > ,
101
101
gid : Option < gid_t > ,
102
102
saw_nul : bool ,
103
+ saw_invalid_env_key : bool ,
103
104
closures : Vec < Box < dyn FnMut ( ) -> io:: Result < ( ) > + Send + Sync > > ,
104
105
groups : Option < Box < [ gid_t ] > > ,
105
106
stdin : Option < Stdio > ,
@@ -193,6 +194,7 @@ impl Command {
193
194
uid : None ,
194
195
gid : None ,
195
196
saw_nul,
197
+ saw_invalid_env_key : false ,
196
198
closures : Vec :: new ( ) ,
197
199
groups : None ,
198
200
stdin : None ,
@@ -217,6 +219,7 @@ impl Command {
217
219
uid : None ,
218
220
gid : None ,
219
221
saw_nul,
222
+ saw_invalid_env_key : false ,
220
223
closures : Vec :: new ( ) ,
221
224
groups : None ,
222
225
stdin : None ,
@@ -279,8 +282,18 @@ impl Command {
279
282
self . create_pidfd
280
283
}
281
284
282
- pub fn saw_nul ( & self ) -> bool {
283
- self . saw_nul
285
+ pub fn validate_input ( & self ) -> io:: Result < ( ) > {
286
+ if self . saw_invalid_env_key {
287
+ Err ( io:: const_io_error!( io:: ErrorKind :: InvalidInput , "env key empty or equals sign found in env key" ) )
288
+ } else if self . saw_nul {
289
+ Err ( io:: const_io_error!( io:: ErrorKind :: InvalidInput , "nul byte found in provided data" ) )
290
+ } else {
291
+ Ok ( ( ) )
292
+ }
293
+ }
294
+
295
+ pub fn saw_invalid_env_key ( & self ) -> bool {
296
+ self . saw_invalid_env_key
284
297
}
285
298
286
299
pub fn get_program ( & self ) -> & OsStr {
@@ -361,7 +374,7 @@ impl Command {
361
374
362
375
pub fn capture_env ( & mut self ) -> Option < CStringArray > {
363
376
let maybe_env = self . env . capture_if_changed ( ) ;
364
- maybe_env. map ( |env| construct_envp ( env, & mut self . saw_nul ) )
377
+ maybe_env. map ( |env| construct_envp ( env, & mut self . saw_nul , & mut self . saw_invalid_env_key ) )
365
378
}
366
379
367
380
#[ allow( dead_code) ]
@@ -426,9 +439,21 @@ impl CStringArray {
426
439
}
427
440
}
428
441
429
- fn construct_envp ( env : BTreeMap < OsString , OsString > , saw_nul : & mut bool ) -> CStringArray {
442
+ fn construct_envp ( env : BTreeMap < OsString , OsString > , saw_nul : & mut bool , saw_invalid_env_key : & mut bool ) -> CStringArray {
430
443
let mut result = CStringArray :: with_capacity ( env. len ( ) ) ;
431
444
for ( mut k, v) in env {
445
+ {
446
+ let mut iter = k. as_bytes ( ) . iter ( ) ;
447
+ if iter. next ( ) . is_none ( ) {
448
+ * saw_invalid_env_key = true ;
449
+ continue ;
450
+ }
451
+ if iter. any ( |& b| b == b'=' ) {
452
+ * saw_invalid_env_key = true ;
453
+ continue ;
454
+ }
455
+ }
456
+
432
457
// Reserve additional space for '=' and null terminator
433
458
k. reserve_exact ( v. len ( ) + 2 ) ;
434
459
k. push ( "=" ) ;
0 commit comments