-
Notifications
You must be signed in to change notification settings - Fork 126
Closed
Description
Using base64::write::EncoderWriter
with a writer that accepts very limited writes leads to EncoderWriter::write_all
calls failing.
To reproduce (playground link)
extern crate base64; // 0.13.0
use std::io::{self, Write};
/// A Writer that limits how much can be written in a single call
struct ShortWriter<'a, W> {
writer: &'a mut W,
max_write_len: usize,
}
impl<'a, W> Write for ShortWriter<'a, W>
where
W: Write,
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let write_len = std::cmp::min(self.max_write_len, buf.len());
let written = self.writer.write(&buf[..write_len])?;
// do some other stuff...
Ok(written)
}
fn flush(&mut self) -> io::Result<()> {
self.writer.flush()
}
}
fn main() {
let contents = vec![b'A'; 100];
let mut vec = Vec::with_capacity(8196);
{
let writer_ = ShortWriter {
writer: &mut vec,
max_write_len: 76,
};
let mut writer = base64::write::EncoderWriter::new(writer_, base64::STANDARD);
writer.write_all(&contents).unwrap();
}
assert_eq!(vec, base64::encode(contents).into_bytes());
}
To reproduce 2 (expanded the default Write::write_all implementation) (playground link)
Click to expand!
extern crate base64; // 0.13.0
use std::io::{self, Write};
/// A Writer that limits how much can be written in a single call
struct ShortWriter<'a, W> {
writer: &'a mut W,
max_write_len: usize,
}
impl<'a, W> Write for ShortWriter<'a, W>
where
W: Write,
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let write_len = std::cmp::min(self.max_write_len, buf.len());
let written = self.writer.write(&buf[..write_len])?;
// do some other stuff...
Ok(written)
}
fn flush(&mut self) -> io::Result<()> {
self.writer.flush()
}
}
fn main() {
let contents = vec![b'A'; 100];
let mut vec = Vec::with_capacity(8196);
{
let writer_ = ShortWriter {
writer: &mut vec,
max_write_len: 76,
};
let mut writer = base64::write::EncoderWriter::new(writer_, base64::STANDARD);
// writer.write_all(&contents).unwrap();
let mut buf: &[u8] = contents.as_ref();
while !buf.is_empty() {
println!("writing");
match writer.write(buf) {
Ok(0) => {
// this should never happen
println!("ignoring zero write");
}
Ok(n) => {
println!("written len: {}", n);
buf = &buf[n..];
},
Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {}
Err(e) => panic!("err: {}", e),
}
}
}
assert_eq!(vec, base64::encode(contents).into_bytes());
}
Expected behavior
Encoding succeeds, and the contents of vec
are the same I would get if I were to call base64::encode(contents)
.
Observed behavior
writer.write_all(&contents)
fails with Custom { kind: WriteZero, error: "failed to write whole buffer" }
Environment
rust: stable
base64: 0.13.0
Metadata
Metadata
Assignees
Labels
No labels