Skip to content

Commit c5b1a6e

Browse files
committed
Add new error case
1 parent fd422ef commit c5b1a6e

File tree

3 files changed

+29
-40
lines changed

3 files changed

+29
-40
lines changed

src/encoder.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ pub enum EncodingFormatError {
1818
TooManyColors,
1919
/// The image has no color palette which is required.
2020
MissingColorPalette,
21+
/// LZW data is not valid for GIF. This may happen when wrong buffer is given to `write_lzw_pre_encoded_frame`
22+
InvalidMinCodeSize,
2123
}
2224

2325
impl error::Error for EncodingFormatError {}
@@ -27,6 +29,7 @@ impl fmt::Display for EncodingFormatError {
2729
match self {
2830
Self::TooManyColors => write!(fmt, "the image has too many colors"),
2931
Self::MissingColorPalette => write!(fmt, "the GIF format requires a color palette but none was given"),
32+
Self::InvalidMinCodeSize => write!(fmt, "LZW data is invalid"),
3033
}
3134
}
3235
}
@@ -314,7 +317,7 @@ impl<W: Write> Encoder<W> {
314317
// empty data is allowed
315318
if let Some(&min_code_size) = frame.buffer.get(0) {
316319
if min_code_size > 11 || min_code_size < 2 {
317-
return Err(EncodingError::from(io::Error::new(io::ErrorKind::InvalidInput, "invalid code size")));
320+
return Err(EncodingError::Format(EncodingFormatError::InvalidMinCodeSize));
318321
}
319322
}
320323

src/reader/decoder.rs

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,6 @@ impl error::Error for DecodingFormatError {
3333
}
3434
}
3535

36-
impl DecodingFormatError {
37-
// Cold hints the optimizer that the error paths are less likely.
38-
//
39-
// This function isn't inlined to reduce code size
40-
// when it's often used with a string literal.
41-
#[cold]
42-
fn new(
43-
err: impl Into<Box<dyn error::Error + Send + Sync>>,
44-
) -> Self {
45-
DecodingFormatError {
46-
underlying: err.into(),
47-
}
48-
}
49-
}
50-
5136
#[derive(Debug)]
5237
/// Decoding error.
5338
pub enum DecodingError {
@@ -58,11 +43,11 @@ pub enum DecodingError {
5843
}
5944

6045
impl DecodingError {
61-
#[inline]
62-
pub(crate) fn format(
63-
err: impl Into<Box<dyn error::Error + Send + Sync>>,
64-
) -> Self {
65-
DecodingError::Format(DecodingFormatError::new(err))
46+
#[cold]
47+
pub(crate) fn format(err: &'static str) -> Self {
48+
DecodingError::Format(DecodingFormatError {
49+
underlying: err.into(),
50+
})
6651
}
6752
}
6853

@@ -93,6 +78,13 @@ impl From<io::Error> for DecodingError {
9378
}
9479
}
9580

81+
impl From<io::ErrorKind> for DecodingError {
82+
#[cold]
83+
fn from(err: io::ErrorKind) -> Self {
84+
DecodingError::Io(io::Error::from(err))
85+
}
86+
}
87+
9688
impl From<DecodingFormatError> for DecodingError {
9789
#[inline]
9890
fn from(err: DecodingFormatError) -> Self {
@@ -260,11 +252,11 @@ impl LzwReader {
260252
Ok(LzwStatus::Done) | Ok(LzwStatus::Ok) => {},
261253
Ok(LzwStatus::NoProgress) => {
262254
if self.check_for_end_code {
263-
return Err(io::Error::new(io::ErrorKind::InvalidData, "No end code in lzw stream"));
255+
return Err(io::Error::new(io::ErrorKind::InvalidData, "no end code in lzw stream"));
264256
}
265257
},
266-
Err(LzwError::InvalidCode) => {
267-
return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid code in LZW stream").into());
258+
Err(err @ LzwError::InvalidCode) => {
259+
return Err(io::Error::new(io::ErrorKind::InvalidData, err).into());
268260
}
269261
}
270262
Ok((decoded.consumed_in, decoded.consumed_out))
@@ -446,7 +438,7 @@ impl StreamingDecoder {
446438
})
447439
);
448440

449-
let b = *buf.get(0).ok_or_else(|| DecodingError::format("empty buf"))?;
441+
let b = *buf.get(0).ok_or_else(|| io::ErrorKind::UnexpectedEof)?;
450442

451443
match self.state {
452444
Magic(i, mut version) => if i < 6 {
@@ -456,7 +448,7 @@ impl StreamingDecoder {
456448
self.version = match &version[3..] {
457449
b"87a" => Version::V87a,
458450
b"89a" => Version::V89a,
459-
_ => return Err(DecodingError::format("unsupported GIF version"))
451+
_ => return Err(DecodingError::format("malformed GIF header"))
460452
};
461453
goto!(U16Byte1(U16Value::ScreenWidth, b))
462454
} else {
@@ -515,7 +507,7 @@ impl StreamingDecoder {
515507
let global_table = global_flags & 0x80 != 0;
516508
let table_size = if global_table {
517509
let table_size = PLTE_CHANNELS * (1 << ((global_flags & 0b111) + 1) as usize);
518-
self.global_color_table.try_reserve_exact(table_size).map_err(|_| io::Error::from(io::ErrorKind::OutOfMemory))?;
510+
self.global_color_table.try_reserve_exact(table_size).map_err(|_| io::ErrorKind::OutOfMemory)?;
519511
table_size
520512
} else {
521513
0usize
@@ -569,7 +561,7 @@ impl StreamingDecoder {
569561
if local_table {
570562
let entries = PLTE_CHANNELS * (1 << (table_size + 1));
571563
let mut pal = Vec::new();
572-
pal.try_reserve_exact(entries).map_err(|_| io::Error::from(io::ErrorKind::OutOfMemory))?;
564+
pal.try_reserve_exact(entries).map_err(|_| io::ErrorKind::OutOfMemory)?;
573565
frame.palette = Some(pal);
574566
goto!(LocalPalette(entries))
575567
} else {
@@ -646,9 +638,7 @@ impl StreamingDecoder {
646638
}
647639
}
648640
} else {
649-
Err(DecodingError::format(
650-
"unknown extention block encountered"
651-
))
641+
Err(DecodingError::format("unknown block type encountered"))
652642
}
653643
}
654644
SkipBlock(left) => {
@@ -699,7 +689,7 @@ impl StreamingDecoder {
699689
(len, len)
700690
},
701691
OutputBuffer::Vec(vec) => {
702-
vec.try_reserve(n).map_err(|_| io::Error::from(io::ErrorKind::OutOfMemory))?;
692+
vec.try_reserve(n).map_err(|_| io::ErrorKind::OutOfMemory)?;
703693
vec.extend_from_slice(&buf[..n]);
704694
(n, n)
705695
},
@@ -773,5 +763,5 @@ impl StreamingDecoder {
773763

774764
#[test]
775765
fn error_cast() {
776-
let _ : Box<dyn error::Error> = DecodingError::Format(DecodingFormatError::new("testing")).into();
766+
let _ : Box<dyn error::Error> = DecodingError::format("testing").into();
777767
}

src/reader/mod.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,7 @@ impl<R: Read> ReadDecoder<R> {
193193
let (consumed, result) = {
194194
let buf = self.reader.fill_buf()?;
195195
if buf.is_empty() {
196-
return Err(DecodingError::format(
197-
"unexpected EOF"
198-
))
196+
return Err(io::ErrorKind::UnexpectedEof.into());
199197
}
200198

201199
// Dead code checks the lifetimes that the later mem::transmute can't.
@@ -327,9 +325,7 @@ impl<R> Decoder<R> where R: Read {
327325
let (width, height) = (frame.width, frame.height);
328326
let pixel_bytes = self.memory_limit
329327
.buffer_size(self.color_output, width, height)
330-
.ok_or_else(|| {
331-
DecodingError::format("image is too large to decode")
332-
})?;
328+
.ok_or_else(|| io::Error::new(io::ErrorKind::OutOfMemory, "image is too large"))?;
333329

334330
debug_assert_eq!(
335331
pixel_bytes, self.buffer_size(),
@@ -411,7 +407,7 @@ impl<R> Decoder<R> where R: Read {
411407
ColorOutput::RGBA => {
412408
let buffer_size = buf.len() / N_CHANNELS;
413409
if buffer_size == 0 {
414-
return Err(DecodingError::Io(io::Error::new(io::ErrorKind::InvalidInput, "odd-sized buffer")));
410+
return Err(DecodingError::format("odd-sized buffer"));
415411
}
416412
if self.buffer.len() < buffer_size {
417413
self.buffer.resize(buffer_size, 0);

0 commit comments

Comments
 (0)