mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 08:53:35 +00:00
Merge #8159
8159: Ignore proc-macro stdout to prevent IPC crash r=edwin0cheng a=edwin0cheng fixes #7954 r? @flodiebold Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
commit
d702f10fb3
@ -55,8 +55,8 @@ pub enum ErrorCode {
|
||||
}
|
||||
|
||||
pub trait Message: Serialize + DeserializeOwned {
|
||||
fn read(inp: &mut impl BufRead) -> io::Result<Option<Self>> {
|
||||
Ok(match read_json(inp)? {
|
||||
fn read(inp: &mut impl BufRead, buf: &mut String) -> io::Result<Option<Self>> {
|
||||
Ok(match read_json(inp, buf)? {
|
||||
None => None,
|
||||
Some(text) => {
|
||||
let mut deserializer = serde_json::Deserializer::from_str(&text);
|
||||
@ -76,14 +76,29 @@ pub trait Message: Serialize + DeserializeOwned {
|
||||
impl Message for Request {}
|
||||
impl Message for Response {}
|
||||
|
||||
fn read_json(inp: &mut impl BufRead) -> io::Result<Option<String>> {
|
||||
let mut buf = String::new();
|
||||
inp.read_line(&mut buf)?;
|
||||
buf.pop(); // Remove trailing '\n'
|
||||
Ok(match buf.len() {
|
||||
0 => None,
|
||||
_ => Some(buf),
|
||||
})
|
||||
fn read_json<'a>(
|
||||
inp: &mut impl BufRead,
|
||||
mut buf: &'a mut String,
|
||||
) -> io::Result<Option<&'a String>> {
|
||||
loop {
|
||||
buf.clear();
|
||||
|
||||
inp.read_line(&mut buf)?;
|
||||
buf.pop(); // Remove trailing '\n'
|
||||
|
||||
if buf.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Some ill behaved macro try to use stdout for debugging
|
||||
// We ignore it here
|
||||
if !buf.starts_with("{") {
|
||||
log::error!("proc-macro tried to print : {}", buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
return Ok(Some(buf));
|
||||
}
|
||||
}
|
||||
|
||||
fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {
|
||||
|
@ -90,8 +90,10 @@ impl ProcMacroProcessSrv {
|
||||
fn client_loop(task_rx: Receiver<Task>, mut process: Process) {
|
||||
let (mut stdin, mut stdout) = process.stdio().expect("couldn't access child stdio");
|
||||
|
||||
let mut buf = String::new();
|
||||
|
||||
for Task { req, result_tx } in task_rx {
|
||||
match send_request(&mut stdin, &mut stdout, req) {
|
||||
match send_request(&mut stdin, &mut stdout, req, &mut buf) {
|
||||
Ok(res) => result_tx.send(res).unwrap(),
|
||||
Err(err) => {
|
||||
log::error!(
|
||||
@ -152,7 +154,8 @@ fn send_request(
|
||||
mut writer: &mut impl Write,
|
||||
mut reader: &mut impl BufRead,
|
||||
req: Request,
|
||||
buf: &mut String,
|
||||
) -> io::Result<Option<Response>> {
|
||||
req.write(&mut writer)?;
|
||||
Response::read(&mut reader)
|
||||
Response::read(&mut reader, buf)
|
||||
}
|
||||
|
@ -6,8 +6,9 @@ use std::io;
|
||||
|
||||
pub fn run() -> io::Result<()> {
|
||||
let mut srv = ProcMacroSrv::default();
|
||||
let mut buf = String::new();
|
||||
|
||||
while let Some(req) = read_request()? {
|
||||
while let Some(req) = read_request(&mut buf)? {
|
||||
let res = match req {
|
||||
msg::Request::ListMacro(task) => srv.list_macros(&task).map(msg::Response::ListMacro),
|
||||
msg::Request::ExpansionMacro(task) => {
|
||||
@ -30,8 +31,8 @@ pub fn run() -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_request() -> io::Result<Option<msg::Request>> {
|
||||
msg::Request::read(&mut io::stdin().lock())
|
||||
fn read_request(buf: &mut String) -> io::Result<Option<msg::Request>> {
|
||||
msg::Request::read(&mut io::stdin().lock(), buf)
|
||||
}
|
||||
|
||||
fn write_response(msg: msg::Response) -> io::Result<()> {
|
||||
|
@ -712,6 +712,10 @@ pub fn foo(_input: TokenStream) -> TokenStream {
|
||||
// We hard code the output here for preventing to use any deps
|
||||
let mut res = TokenStream::new();
|
||||
|
||||
// ill behaved proc-macro will use the stdout
|
||||
// we should ignore it
|
||||
println!("I am bad guy");
|
||||
|
||||
// impl Bar for Foo { fn bar() {} }
|
||||
let mut tokens = vec![t!("impl"), t!("Bar"), t!("for"), t!("Foo")];
|
||||
let mut fn_stream = TokenStream::new();
|
||||
|
Loading…
Reference in New Issue
Block a user