Skip to content

Commit 17eaf66

Browse files
committed
---
yaml --- r: 114069 b: refs/heads/master c: d9eca56 h: refs/heads/master i: 114067: 2fe0326 v: v3
1 parent 832f25b commit 17eaf66

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: b6cce7ea5497977291f4ae57937360978e764e41
2+
refs/heads/master: d9eca56c065d27498a0e5fbd20ad114063c96281
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: ec0258a381b88b5574e3f8ce72ae553ac3a574b7
55
refs/heads/try: 7c6c492fb2af9a85f21ff952942df3523b22fd17

trunk/src/liblibc/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4195,7 +4195,7 @@ pub mod funcs {
41954195
use types::os::arch::c95::{c_uint};
41964196
use types::os::arch::extra::{BOOL, DWORD, SIZE_T, HMODULE,
41974197
LPCWSTR, LPWSTR,
4198-
LPCH, LPDWORD, LPVOID,
4198+
LPWCH, LPDWORD, LPVOID,
41994199
LPCVOID, LPOVERLAPPED,
42004200
LPSECURITY_ATTRIBUTES,
42014201
LPSTARTUPINFO,
@@ -4212,8 +4212,8 @@ pub mod funcs {
42124212
-> DWORD;
42134213
pub fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR)
42144214
-> BOOL;
4215-
pub fn GetEnvironmentStringsA() -> LPCH;
4216-
pub fn FreeEnvironmentStringsA(env_ptr: LPCH) -> BOOL;
4215+
pub fn GetEnvironmentStringsW() -> LPWCH;
4216+
pub fn FreeEnvironmentStringsW(env_ptr: LPWCH) -> BOOL;
42174217
pub fn GetModuleFileNameW(hModule: HMODULE,
42184218
lpFilename: LPWSTR,
42194219
nSize: DWORD)

trunk/src/libstd/os.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
use clone::Clone;
3232
use container::Container;
3333
use libc;
34-
use libc::{c_char, c_void, c_int};
34+
use libc::{c_void, c_int};
3535
use option::{Some, None, Option};
3636
use os;
3737
use ops::Drop;
@@ -49,6 +49,8 @@ use vec::Vec;
4949

5050
#[cfg(unix)]
5151
use c_str::ToCStr;
52+
#[cfg(unix)]
53+
use libc::c_char;
5254
#[cfg(windows)]
5355
use str::OwnedStr;
5456

@@ -186,22 +188,42 @@ pub fn env_as_bytes() -> Vec<(~[u8],~[u8])> {
186188
unsafe {
187189
#[cfg(windows)]
188190
unsafe fn get_env_pairs() -> Vec<~[u8]> {
189-
use c_str;
191+
use slice::raw;
190192

191193
use libc::funcs::extra::kernel32::{
192-
GetEnvironmentStringsA,
193-
FreeEnvironmentStringsA
194+
GetEnvironmentStringsW,
195+
FreeEnvironmentStringsW
194196
};
195-
let ch = GetEnvironmentStringsA();
197+
let ch = GetEnvironmentStringsW();
196198
if ch as uint == 0 {
197199
fail!("os::env() failure getting env string from OS: {}",
198200
os::last_os_error());
199201
}
202+
// Here, we lossily decode the string as UTF16.
203+
//
204+
// The docs suggest that the result should be in Unicode, but
205+
// Windows doesn't guarantee it's actually UTF16 -- it doesn't
206+
// validate the environment string passed to CreateProcess nor
207+
// SetEnvironmentVariable. Yet, it's unlikely that returning a
208+
// raw u16 buffer would be of practical use since the result would
209+
// be inherently platform-dependent and introduce additional
210+
// complexity to this code.
211+
//
212+
// Using the non-Unicode version of GetEnvironmentStrings is even
213+
// worse since the result is in an OEM code page. Characters that
214+
// can't be encoded in the code page would be turned into question
215+
// marks.
200216
let mut result = Vec::new();
201-
c_str::from_c_multistring(ch as *c_char, None, |cstr| {
202-
result.push(cstr.as_bytes_no_nul().to_owned());
203-
});
204-
FreeEnvironmentStringsA(ch);
217+
let mut i = 0;
218+
while *ch.offset(i) != 0 {
219+
let p = &*ch.offset(i);
220+
let len = ptr::position(p, |c| *c == 0);
221+
raw::buf_as_slice(p, len, |s| {
222+
result.push(str::from_utf16_lossy(s).into_bytes());
223+
});
224+
i += len as int + 1;
225+
}
226+
FreeEnvironmentStringsW(ch);
205227
result
206228
}
207229
#[cfg(unix)]

0 commit comments

Comments
 (0)