Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helper alloc_os_str_as_c_str and use it in env_var emulation #1098

Closed
wants to merge 12 commits into from
52 changes: 52 additions & 0 deletions src/shims/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,29 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
})
}

fn getenvironmentvariablew(
&mut self,
name_op: OpTy<'tcx, Tag>,
lpbuffer_op: OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, u32> {
let this = self.eval_context_mut();

let name_ptr = this.read_scalar(name_op)?.not_undef()?;
let name = this.memory.read_wide_str(name_ptr)?;
let lpbuf_ptr = this.read_scalar(buffer_op)?.not_undef()?;
Ok(match this.machine.env_vars.map.get(name) {
Some(var_ptr) => {
let var = this.memory.read_wide_str(var_ptr);
// Write contents of env_var to lpBuffer
this.memory.write_bytes(lpbuf_ptr, var);
// `var` is a byte slice, but will be interpreted as unicode string.
// one unicode character equals 2 bytes.
(var.len() >> 1) as u32
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
}
None => 0,
})
}

fn setenv(
&mut self,
name_op: OpTy<'tcx, Tag>,
Expand Down Expand Up @@ -92,6 +115,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
}

fn setenvironmentvariablew(
&mut self,
name_op: OpTy<'tcx, Tag>,
value_op: OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let name_ptr = this.read_scalar(name_op)?.not_undef()?;
let value_ptr = this.read_scalar(value_op)?.not_undef()?;
let value = this.memory.read_wide_str(value_ptr)?;
let mut new = None;
if !this.is_null(name_ptr)? {
let name = this.memory.read_wide_str(name_ptr)?;
if !name.is_empty() && !name.contains(&b'=') {
RalfJung marked this conversation as resolved.
Show resolved Hide resolved
new = Some((name.to_owned(), value.to_owned()));
}
}
if let Some((name, value)) = new {
let var_ptr = alloc_env_var(&name, &value, &mut this.memory);
if let Some(var) = this.machine.env_vars.map.insert(name.to_owned(), var_ptr) {
this.memory
.deallocate(var, None, MiriMemoryKind::Env.into())?;
}
Ok(1) // return non-zero if success
} else {
Ok(0) // return upon failure
}
}

fn unsetenv(&mut self, name_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

Expand Down
17 changes: 14 additions & 3 deletions src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -913,9 +913,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.write_null(dest)?;
}
"GetEnvironmentVariableW" => {
// This is not the env var you are looking for.
this.set_last_error(Scalar::from_u32(203))?; // ERROR_ENVVAR_NOT_FOUND
this.write_null(dest)?;
// args[0] : LPCWSTR lpName (32-bit ptr to a const string of 16-bit Unicode chars)
// args[1] : LPWSTR lpBuffer (32-bit pointer to a string of 16-bit Unicode chars)
// lpBuffer : ptr to buffer that receives contents of the env_var as a null-terminated string.
// Return `# of chars` stored in the buffer pointed to by lpBuffer, excluding null-terminator.
// Return 0 upon failure.
let result = this.getenvironmentvariablew(args[0], args[1])?;
this.write_scalar(Scalar::from_u32(result, dest.layout.size), dest)?;
}
"SetEnvironmentVariableW" => {
// args[0] : LPCWSTR lpName (32-bit ptr to a const string of 16-bit Unicode chars)
// args[1] : LPCWSTR lpValue (32-bit ptr to a const string of 16-bit Unicode chars)
// Return nonzero if success, else return 0.
let result = this.setenvironmentvariablew(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
}
"GetCommandLineW" => {
this.write_scalar(this.machine.cmd_line.expect("machine must be initialized"), dest)?;
Expand Down