(env: ArgMapping, vm: &VirtualMachine)
| 404 | } |
| 405 | |
| 406 | fn getenvironment(env: ArgMapping, vm: &VirtualMachine) -> PyResult<Vec<u16>> { |
| 407 | let keys = env.mapping().keys(vm)?; |
| 408 | let values = env.mapping().values(vm)?; |
| 409 | |
| 410 | let keys = ArgSequence::try_from_object(vm, keys)?.into_vec(); |
| 411 | let values = ArgSequence::try_from_object(vm, values)?.into_vec(); |
| 412 | |
| 413 | if keys.len() != values.len() { |
| 414 | return Err(vm.new_runtime_error("environment changed size during iteration")); |
| 415 | } |
| 416 | |
| 417 | // Deduplicate case-insensitive keys, keeping the last value |
| 418 | use std::collections::HashMap; |
| 419 | let mut last_entry: HashMap<String, widestring::WideString> = HashMap::new(); |
| 420 | for (k, v) in keys.into_iter().zip(values.into_iter()) { |
| 421 | let k = PyStrRef::try_from_object(vm, k)?; |
| 422 | let k = k.expect_str(); |
| 423 | let v = PyStrRef::try_from_object(vm, v)?; |
| 424 | let v = v.expect_str(); |
| 425 | if k.contains('\0') || v.contains('\0') { |
| 426 | return Err(crate::exceptions::cstring_error(vm)); |
| 427 | } |
| 428 | if k.is_empty() || k[1..].contains('=') { |
| 429 | return Err(vm.new_value_error("illegal environment variable name")); |
| 430 | } |
| 431 | let key_upper = k.to_uppercase(); |
| 432 | let mut entry = widestring::WideString::new(); |
| 433 | entry.push_str(k); |
| 434 | entry.push_str("="); |
| 435 | entry.push_str(v); |
| 436 | entry.push_str("\0"); |
| 437 | last_entry.insert(key_upper, entry); |
| 438 | } |
| 439 | |
| 440 | // Sort by uppercase key for case-insensitive ordering |
| 441 | let mut entries: Vec<(String, widestring::WideString)> = last_entry.into_iter().collect(); |
| 442 | entries.sort_by(|a, b| a.0.cmp(&b.0)); |
| 443 | |
| 444 | let mut out = widestring::WideString::new(); |
| 445 | for (_, entry) in entries { |
| 446 | out.push(entry); |
| 447 | } |
| 448 | // Each entry ends with \0, so one more \0 terminates the block. |
| 449 | // For empty env, we need \0\0 as a valid empty environment block. |
| 450 | if out.is_empty() { |
| 451 | out.push_str("\0"); |
| 452 | } |
| 453 | out.push_str("\0"); |
| 454 | Ok(out.into_vec()) |
| 455 | } |
| 456 | |
| 457 | struct AttrList { |
| 458 | handlelist: Option<Vec<usize>>, |
no test coverage detected