mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-09 22:28:21 +00:00
fix(c-api) Don't drain the entire captured stream when reading a small range.
We use `VecDeque::drain` to read the captured stream, zipped with the given buffer. We could expect that only the yielded items from the `drain` will be removed, but actually no. Reading [the documentation](https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.drain): > Note 1: The element `range` is removed even if the iterator is not > consumed until the end. So by using a range like `..` will drain the entire captured stream, whatever we read from it. Said differently, if the given buffer length is smaller than the captured stream, the first read will drain the entire captured stream. This patch fixes the problem by specifying a better range: `..min(inner_buffer.len(), oc.buffer.len())`. With this new range, it's actually useless to increment `num_bytes_written`, we already know ahead of time the amount of bytes we are going to read. Consequently, the patch simplifies this code a little bit more.
This commit is contained in:
@@ -13,6 +13,7 @@ use super::{
|
||||
// required due to really weird Rust resolution rules for macros
|
||||
// https://github.com/rust-lang/rust/issues/57966
|
||||
use crate::error::{update_last_error, CApiError};
|
||||
use std::cmp::min;
|
||||
use std::convert::TryFrom;
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw::c_char;
|
||||
@@ -275,12 +276,16 @@ pub unsafe extern "C" fn wasi_env_read_stderr(
|
||||
|
||||
fn read_inner(wasi_file: &mut Box<dyn WasiFile>, inner_buffer: &mut [u8]) -> isize {
|
||||
if let Some(oc) = wasi_file.downcast_mut::<capture_files::OutputCapturer>() {
|
||||
let mut num_bytes_written = 0;
|
||||
for (address, value) in inner_buffer.iter_mut().zip(oc.buffer.drain(..)) {
|
||||
let total_to_read = min(inner_buffer.len(), oc.buffer.len());
|
||||
|
||||
for (address, value) in inner_buffer
|
||||
.iter_mut()
|
||||
.zip(oc.buffer.drain(..total_to_read))
|
||||
{
|
||||
*address = value;
|
||||
num_bytes_written += 1;
|
||||
}
|
||||
num_bytes_written
|
||||
|
||||
total_to_read as isize
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user