don't leak UnixEnvVars impl details into get_env_var

This commit is contained in:
Ralf Jung 2024-04-29 17:33:35 +02:00
parent 9bed19edc4
commit 7afef08b6d
2 changed files with 19 additions and 13 deletions

View File

@ -106,15 +106,7 @@ fn get_env_var(&mut self, name: &OsStr) -> InterpResult<'tcx, Option<OsString>>
let this = self.eval_context_ref(); let this = self.eval_context_ref();
match &this.machine.env_vars { match &this.machine.env_vars {
EnvVars::Uninit => return Ok(None), EnvVars::Uninit => return Ok(None),
EnvVars::Unix(vars) => { EnvVars::Unix(vars) => vars.get(this, name),
let var_ptr = vars.get(this, name)?;
if let Some(ptr) = var_ptr {
let var = this.read_os_str_from_c_str(ptr)?;
Ok(Some(var.to_owned()))
} else {
Ok(None)
}
}
EnvVars::Windows(vars) => vars.get(name), EnvVars::Windows(vars) => vars.get(name),
} }
} }

View File

@ -71,9 +71,7 @@ pub(crate) fn environ(&self) -> Pointer<Option<Provenance>> {
self.environ.ptr() self.environ.ptr()
} }
/// Implementation detail for [`InterpCx::get_env_var`]. This basically does `getenv`, complete fn get_ptr<'mir>(
/// with the reads of the environment, but returns an [`OsString`] instead of a pointer.
pub(crate) fn get<'mir>(
&self, &self,
ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>,
name: &OsStr, name: &OsStr,
@ -91,6 +89,22 @@ pub(crate) fn get<'mir>(
)?; )?;
Ok(Some(var_ptr)) Ok(Some(var_ptr))
} }
/// Implementation detail for [`InterpCx::get_env_var`]. This basically does `getenv`, complete
/// with the reads of the environment, but returns an [`OsString`] instead of a pointer.
pub(crate) fn get<'mir>(
&self,
ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>,
name: &OsStr,
) -> InterpResult<'tcx, Option<OsString>> {
let var_ptr = self.get_ptr(ecx, name)?;
if let Some(ptr) = var_ptr {
let var = ecx.read_os_str_from_c_str(ptr)?;
Ok(Some(var.to_owned()))
} else {
Ok(None)
}
}
} }
fn alloc_env_var<'mir, 'tcx>( fn alloc_env_var<'mir, 'tcx>(
@ -137,7 +151,7 @@ fn getenv(
let name_ptr = this.read_pointer(name_op)?; let name_ptr = this.read_pointer(name_op)?;
let name = this.read_os_str_from_c_str(name_ptr)?; let name = this.read_os_str_from_c_str(name_ptr)?;
let var_ptr = this.machine.env_vars.unix().get(this, name)?; let var_ptr = this.machine.env_vars.unix().get_ptr(this, name)?;
Ok(var_ptr.unwrap_or_else(Pointer::null)) Ok(var_ptr.unwrap_or_else(Pointer::null))
} }