| ... | @@ -527,31 +527,33 @@ pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 { | ... | @@ -527,31 +527,33 @@ pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 { |
| 527 | @compileError("Windows-only"); | 527 | @compileError("Windows-only"); |
| 528 | } | 528 | } |
| 529 | const key_slice = mem.sliceTo(key, 0); | 529 | const key_slice = mem.sliceTo(key, 0); |
| | 530 | // '=' anywhere but the start makes this an invalid environment variable name |
| | 531 | if (key_slice.len > 0 and std.mem.indexOfScalar(u16, key_slice[1..], '=') != null) { |
| | 532 | return null; |
| | 533 | } |
| 530 | const ptr = windows.peb().ProcessParameters.Environment; | 534 | const ptr = windows.peb().ProcessParameters.Environment; |
| 531 | var i: usize = 0; | 535 | var i: usize = 0; |
| 532 | while (ptr[i] != 0) { | 536 | while (ptr[i] != 0) { |
| 533 | const key_start = i; | 537 | const key_value = mem.sliceTo(ptr[i..], 0); |
| 534 | | 538 | |
| 535 | // There are some special environment variables that start with =, | 539 | // There are some special environment variables that start with =, |
| 536 | // so we need a special case to not treat = as a key/value separator | 540 | // so we need a special case to not treat = as a key/value separator |
| 537 | // if it's the first character. | 541 | // if it's the first character. |
| 538 | // https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133 | 542 | // https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133 |
| 539 | if (ptr[key_start] == '=') i += 1; | 543 | const equal_search_start: usize = if (key_value[0] == '=') 1 else 0; |
| 540 | | 544 | const equal_index = std.mem.indexOfScalarPos(u16, key_value, equal_search_start, '=') orelse { |
| 541 | while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {} | 545 | // This is enforced by CreateProcess. |
| 542 | const this_key = ptr[key_start..i]; | 546 | // If violated, CreateProcess will fail with INVALID_PARAMETER. |
| 543 | | 547 | unreachable; // must contain a = |
| 544 | if (ptr[i] == '=') i += 1; | 548 | }; |
| 545 | | | |
| 546 | const value_start = i; | | |
| 547 | while (ptr[i] != 0) : (i += 1) {} | | |
| 548 | const this_value = ptr[value_start..i :0]; | | |
| 549 | | 549 | |
| | 550 | const this_key = key_value[0..equal_index]; |
| 550 | if (windows.eqlIgnoreCaseWTF16(key_slice, this_key)) { | 551 | if (windows.eqlIgnoreCaseWTF16(key_slice, this_key)) { |
| 551 | return this_value; | 552 | return key_value[equal_index + 1 ..]; |
| 552 | } | 553 | } |
| 553 | | 554 | |
| 554 | i += 1; // skip over null byte | 555 | // skip past the NUL terminator |
| | 556 | i += key_value.len + 1; |
| 555 | } | 557 | } |
| 556 | return null; | 558 | return null; |
| 557 | } | 559 | } |