mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 01:43:22 +00:00
Clone the reader to prevent cursor misplacement in ReadCString
This commit is contained in:
@ -204,13 +204,15 @@ impl ReadCString for VmReader<'_, Fallible> {
|
||||
);
|
||||
|
||||
// Handle the rest of the bytes in bulk
|
||||
let mut cloned_reader = self.clone();
|
||||
while (buffer.len() + mem::size_of::<usize>()) <= max_len {
|
||||
let Ok(word) = self.read_val::<usize>() else {
|
||||
let Ok(word) = cloned_reader.read_val::<usize>() else {
|
||||
break;
|
||||
};
|
||||
|
||||
if has_zero(word) {
|
||||
for byte in word.to_ne_bytes() {
|
||||
self.skip(1);
|
||||
buffer.push(byte);
|
||||
if byte == 0 {
|
||||
return Ok(CString::from_vec_with_nul(buffer)
|
||||
@ -220,6 +222,7 @@ impl ReadCString for VmReader<'_, Fallible> {
|
||||
unreachable!("The branch should never be reached unless `has_zero` has bugs.")
|
||||
}
|
||||
|
||||
self.skip(size_of::<usize>());
|
||||
buffer.extend_from_slice(&word.to_ne_bytes());
|
||||
}
|
||||
|
||||
@ -267,3 +270,29 @@ fn check_vaddr(va: Vaddr) -> Result<()> {
|
||||
const fn is_addr_aligned(addr: usize) -> bool {
|
||||
(addr & (mem::size_of::<usize>() - 1)) == 0
|
||||
}
|
||||
|
||||
#[cfg(ktest)]
|
||||
mod test {
|
||||
use ostd::prelude::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[ktest]
|
||||
fn read_multiple_cstring() {
|
||||
let mut buffer = vec![0u8; 100];
|
||||
|
||||
let str1 = CString::new("hello").unwrap();
|
||||
let str2 = CString::new("world!").unwrap();
|
||||
|
||||
let mut writer = VmWriter::from(buffer.as_mut_slice());
|
||||
writer.write(&mut VmReader::from(str1.as_bytes_with_nul()));
|
||||
writer.write(&mut VmReader::from(str2.as_bytes_with_nul()));
|
||||
drop(writer);
|
||||
|
||||
let mut reader = VmReader::from(buffer.as_slice()).to_fallible();
|
||||
let read_str1 = reader.read_cstring().unwrap();
|
||||
assert_eq!(read_str1, str1);
|
||||
let read_str2 = reader.read_cstring().unwrap();
|
||||
assert_eq!(read_str2, str2);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user