Skip to content

Commit 038fe86

Browse files
committed
Fix read_wide_string implementation
1 parent f49a945 commit 038fe86

File tree

2 files changed

+14
-12
lines changed

2 files changed

+14
-12
lines changed

src/helpers.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -918,11 +918,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
918918
mut ptr: Pointer<Option<Provenance>>,
919919
size: Size,
920920
align: Align,
921-
) -> InterpResult<'tcx, Size> {
921+
) -> InterpResult<'tcx, u64> {
922922
let this = self.eval_context_ref();
923923
this.check_ptr_align(ptr, align)?;
924924

925-
let mut len = Size::ZERO;
925+
let mut len = 0;
926926
loop {
927927
// FIXME: We are re-getting the allocation each time around the loop.
928928
// Would be nice if we could somehow "extend" an existing AllocRange.
@@ -931,25 +931,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
931931
if c == 0 {
932932
break;
933933
} else {
934-
len += Size::from_bytes(1);
934+
len += 1;
935935
ptr = ptr.offset(size, this)?;
936936
}
937937
}
938938
Ok(len)
939939
}
940940

941941
/// Calculates the length of a null terminated string of bytes.
942-
fn strlen(&self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, Size> {
942+
fn strlen(&self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, u64> {
943943
self.generic_strlen(ptr, Size::from_bytes(1), Align::from_bytes(1).unwrap())
944944
}
945945

946946
/// Calculates the length of a null terminated string of u16.
947-
fn u16_strlen(&self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, Size> {
947+
fn u16_strlen(&self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, u64> {
948948
self.generic_strlen(ptr, Size::from_bytes(2), Align::from_bytes(2).unwrap())
949949
}
950950

951951
/// Calculates the length of a null terminated string of wchar_t.
952-
fn wchar_t_strlen(&self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, Size> {
952+
fn wchar_t_strlen(&self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, u64> {
953953
let this = self.eval_context_ref();
954954
let wchar_t = this.libc_ty_layout("wchar_t");
955955
self.generic_strlen(ptr, wchar_t.size, wchar_t.align.abi)
@@ -976,7 +976,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
976976
'mir: 'a,
977977
{
978978
let this = self.eval_context_ref();
979-
let len = this.strlen(ptr)?;
979+
let len = Size::from_bytes(this.strlen(ptr)?);
980980
this.read_bytes_ptr_strip_provenance(ptr, len)
981981
}
982982

@@ -1014,8 +1014,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10141014
{
10151015
let this = self.eval_context_ref();
10161016
let len = this.u16_strlen(ptr)?;
1017-
let bytes = this.read_bytes_ptr_strip_provenance(ptr, len)?;
1018-
unsafe { Ok(bytes.align_to::<u16>().1) }
1017+
let bytes = this.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(2 * len))?;
1018+
unsafe {
1019+
Ok(std::slice::from_raw_parts(bytes.as_ptr().cast::<u16>(), len.try_into().unwrap()))
1020+
}
10191021
}
10201022

10211023
/// Helper function to write a sequence of u16 with an added 0x0000-terminator, which is what

src/shims/foreign_items.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -804,14 +804,14 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
804804
let ptr = this.read_pointer(ptr)?;
805805
// This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
806806
let n = this.strlen(ptr)?;
807-
this.write_scalar(Scalar::from_target_usize(n.bytes(), this), dest)?;
807+
this.write_scalar(Scalar::from_target_usize(n, this), dest)?;
808808
}
809809
"wcslen" => {
810810
let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
811811
let ptr = this.read_pointer(ptr)?;
812812
// This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
813813
let n = this.wchar_t_strlen(ptr)?;
814-
this.write_scalar(Scalar::from_target_usize(n.bytes(), this), dest)?;
814+
this.write_scalar(Scalar::from_target_usize(n, this), dest)?;
815815
}
816816
"memcpy" => {
817817
let [ptr_dest, ptr_src, n] =
@@ -840,7 +840,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
840840
// That is probably overly cautious, but there also is no fundamental
841841
// reason to have `strcpy` destroy pointer provenance.
842842
// This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
843-
let n = this.strlen(ptr_src)?.bytes().checked_add(1).unwrap();
843+
let n = this.strlen(ptr_src)?.checked_add(1).unwrap();
844844
this.mem_copy(ptr_src, ptr_dest, Size::from_bytes(n), true)?;
845845
this.write_pointer(ptr_dest, dest)?;
846846
}

0 commit comments

Comments
 (0)