Use bytes, not strings, for stdio observers (#885)
Previously, the `CommandExecutor` attempted to decode its child process's stdout and stderr as UTF-8 `String`s. This could fail if the output was not UTF-8. However, the `Std{Out,Err}Observer`s should probably be able to be used in such a situation - Consider fuzzing `echo` with a random `BytesInput`. The fix is to not decode the output, but rather directly store and provide the bytes of stdout/stderr in the observers.
This commit is contained in:
parent
1486c204eb
commit
893f284482
@ -1,5 +1,5 @@
|
||||
//! The command executor executes a sub program for each run
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use alloc::vec::Vec;
|
||||
use core::{
|
||||
fmt::{self, Debug, Formatter},
|
||||
marker::PhantomData,
|
||||
@ -335,21 +335,21 @@ where
|
||||
};
|
||||
|
||||
if self.observers.observes_stderr() {
|
||||
let mut stderr = String::new();
|
||||
let mut stderr = Vec::new();
|
||||
child.stderr.as_mut().ok_or_else(|| {
|
||||
Error::illegal_state(
|
||||
"Observer tries to read stderr, but stderr was not `Stdio::pipe` in CommandExecutor",
|
||||
)
|
||||
})?.read_to_string(&mut stderr)?;
|
||||
})?.read_to_end(&mut stderr)?;
|
||||
self.observers.observe_stderr(&stderr);
|
||||
}
|
||||
if self.observers.observes_stdout() {
|
||||
let mut stdout = String::new();
|
||||
let mut stdout = Vec::new();
|
||||
child.stdout.as_mut().ok_or_else(|| {
|
||||
Error::illegal_state(
|
||||
"Observer tries to read stdout, but stdout was not `Stdio::pipe` in CommandExecutor",
|
||||
)
|
||||
})?.read_to_string(&mut stdout)?;
|
||||
})?.read_to_end(&mut stdout)?;
|
||||
self.observers.observe_stdout(&stdout);
|
||||
}
|
||||
|
||||
|
@ -151,13 +151,13 @@ where
|
||||
}
|
||||
|
||||
/// Runs `observe_stdout` for all stdout observers in the list
|
||||
fn observe_stdout(&mut self, stdout: &str) {
|
||||
fn observe_stdout(&mut self, stdout: &[u8]) {
|
||||
self.primary.as_mut().observe_stderr(stdout);
|
||||
self.secondary.as_mut().observe_stderr(stdout);
|
||||
}
|
||||
|
||||
/// Runs `observe_stderr` for all stderr observers in the list
|
||||
fn observe_stderr(&mut self, stderr: &str) {
|
||||
fn observe_stderr(&mut self, stderr: &[u8]) {
|
||||
self.primary.as_mut().observe_stderr(stderr);
|
||||
self.secondary.as_mut().observe_stderr(stderr);
|
||||
}
|
||||
|
@ -106,13 +106,13 @@ where
|
||||
/// To use this, always return `true` from `observes_stdout`
|
||||
#[inline]
|
||||
#[allow(unused_variables)]
|
||||
fn observe_stdout(&mut self, stdout: &str) {}
|
||||
fn observe_stdout(&mut self, stdout: &[u8]) {}
|
||||
|
||||
/// React to new `stderr`
|
||||
/// To use this, always return `true` from `observes_stderr`
|
||||
#[inline]
|
||||
#[allow(unused_variables)]
|
||||
fn observe_stderr(&mut self, stderr: &str) {}
|
||||
fn observe_stderr(&mut self, stderr: &[u8]) {}
|
||||
}
|
||||
|
||||
/// Defines the observer type shared across traits of the type.
|
||||
@ -155,9 +155,9 @@ where
|
||||
fn observes_stderr(&self) -> bool;
|
||||
|
||||
/// Runs `observe_stdout` for all stdout observers in the list
|
||||
fn observe_stdout(&mut self, stdout: &str);
|
||||
fn observe_stdout(&mut self, stdout: &[u8]);
|
||||
/// Runs `observe_stderr` for all stderr observers in the list
|
||||
fn observe_stderr(&mut self, stderr: &str);
|
||||
fn observe_stderr(&mut self, stderr: &[u8]);
|
||||
}
|
||||
|
||||
impl<S> ObserversTuple<S> for ()
|
||||
@ -205,12 +205,12 @@ where
|
||||
/// Runs `observe_stdout` for all stdout observers in the list
|
||||
#[inline]
|
||||
#[allow(unused_variables)]
|
||||
fn observe_stdout(&mut self, stdout: &str) {}
|
||||
fn observe_stdout(&mut self, stdout: &[u8]) {}
|
||||
|
||||
/// Runs `observe_stderr` for all stderr observers in the list
|
||||
#[inline]
|
||||
#[allow(unused_variables)]
|
||||
fn observe_stderr(&mut self, stderr: &str) {}
|
||||
fn observe_stderr(&mut self, stderr: &[u8]) {}
|
||||
}
|
||||
|
||||
impl<Head, Tail, S> ObserversTuple<S> for (Head, Tail)
|
||||
@ -263,14 +263,14 @@ where
|
||||
|
||||
/// Runs `observe_stdout` for all stdout observers in the list
|
||||
#[inline]
|
||||
fn observe_stdout(&mut self, stdout: &str) {
|
||||
fn observe_stdout(&mut self, stdout: &[u8]) {
|
||||
self.0.observe_stdout(stdout);
|
||||
self.1.observe_stdout(stdout);
|
||||
}
|
||||
|
||||
/// Runs `observe_stderr` for all stderr observers in the list
|
||||
#[inline]
|
||||
fn observe_stderr(&mut self, stderr: &str) {
|
||||
fn observe_stderr(&mut self, stderr: &[u8]) {
|
||||
self.0.observe_stderr(stderr);
|
||||
self.1.observe_stderr(stderr);
|
||||
}
|
||||
@ -991,10 +991,10 @@ pub mod pybind {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn observe_stderr(&mut self, _: &str) {}
|
||||
fn observe_stderr(&mut self, _: &[u8]) {}
|
||||
|
||||
#[inline]
|
||||
fn observe_stdout(&mut self, _: &str) {}
|
||||
fn observe_stdout(&mut self, _: &[u8]) {}
|
||||
}
|
||||
|
||||
impl MatchName for PythonObserversTuple {
|
||||
|
@ -269,8 +269,8 @@ where
|
||||
}
|
||||
|
||||
/// Do nothing on new `stderr`
|
||||
fn observe_stderr(&mut self, stderr: &str) {
|
||||
self.parse_asan_output(stderr);
|
||||
fn observe_stderr(&mut self, stderr: &[u8]) {
|
||||
self.parse_asan_output(&String::from_utf8_lossy(stderr));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
//! For example, they are supported on the [`crate::executors::CommandExecutor`].
|
||||
|
||||
use alloc::string::String;
|
||||
use std::vec::Vec;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -15,7 +16,7 @@ pub struct StdOutObserver {
|
||||
/// The name of the observer.
|
||||
pub name: String,
|
||||
/// The stdout of the target during its last execution.
|
||||
pub stdout: Option<String>,
|
||||
pub stdout: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
/// An observer that captures stdout of a target.
|
||||
@ -37,7 +38,7 @@ where
|
||||
}
|
||||
|
||||
/// React to new `stdout`
|
||||
fn observe_stdout(&mut self, stdout: &str) {
|
||||
fn observe_stdout(&mut self, stdout: &[u8]) {
|
||||
self.stdout = Some(stdout.into());
|
||||
}
|
||||
}
|
||||
@ -55,7 +56,7 @@ pub struct StdErrObserver {
|
||||
/// The name of the observer.
|
||||
pub name: String,
|
||||
/// The stderr of the target during its last execution.
|
||||
pub stderr: Option<String>,
|
||||
pub stderr: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
/// An observer that captures stderr of a target.
|
||||
@ -77,7 +78,7 @@ where
|
||||
}
|
||||
|
||||
/// React to new `stderr`
|
||||
fn observe_stderr(&mut self, stderr: &str) {
|
||||
fn observe_stderr(&mut self, stderr: &[u8]) {
|
||||
self.stderr = Some(stderr.into());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user