aboutsummaryrefslogtreecommitdiff
path: root/matroska
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-08-05 11:51:26 +0200
committermetamuffin <metamuffin@disroot.org>2023-08-05 11:51:26 +0200
commit7cba183debcf2cefd90b4c1e7a630fb0c2152d06 (patch)
tree4d662af700078a2b53df08371f31bba0ccd1a216 /matroska
parent4a0f08126d80dc589e3c97bf0a07571b8b828a74 (diff)
downloadjellything-7cba183debcf2cefd90b4c1e7a630fb0c2152d06.tar
jellything-7cba183debcf2cefd90b4c1e7a630fb0c2152d06.tar.bz2
jellything-7cba183debcf2cefd90b4c1e7a630fb0c2152d06.tar.zst
(semi-)proper error handling in matroska
Diffstat (limited to 'matroska')
-rw-r--r--matroska/Cargo.toml2
-rw-r--r--matroska/src/bin/experiment.rs11
-rw-r--r--matroska/src/bin/mkvdump.rs7
-rw-r--r--matroska/src/block.rs2
-rw-r--r--matroska/src/error.rs19
-rw-r--r--matroska/src/lib.rs4
-rw-r--r--matroska/src/read.rs45
-rw-r--r--matroska/src/unflatten.rs3
-rw-r--r--matroska/src/write.rs17
9 files changed, 67 insertions, 43 deletions
diff --git a/matroska/Cargo.toml b/matroska/Cargo.toml
index e38e028..01a3be9 100644
--- a/matroska/Cargo.toml
+++ b/matroska/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
[dependencies]
ebml_derive = { path = "../ebml_derive" }
-anyhow = "1.0.72"
log = "0.4.19"
env_logger = "0.10.0"
+thiserror = "1.0.44"
diff --git a/matroska/src/bin/experiment.rs b/matroska/src/bin/experiment.rs
index fe3096e..4a8c420 100644
--- a/matroska/src/bin/experiment.rs
+++ b/matroska/src/bin/experiment.rs
@@ -11,10 +11,10 @@ use std::{
io::{stdout, BufReader, BufWriter},
};
-fn main() -> anyhow::Result<()> {
+fn main() {
env_logger::init_from_env("LOG");
let path = std::env::args().nth(1).unwrap();
- let mut r = EbmlReader::new(BufReader::new(File::open(path)?));
+ let mut r = EbmlReader::new(BufReader::new(File::open(path).unwrap()));
let mut w = EbmlWriter::new(BufWriter::new(stdout()), 0);
// r.seek(
@@ -24,11 +24,10 @@ fn main() -> anyhow::Result<()> {
// .unwrap();
while let Some(tag) = r.next() {
- let tag = tag?;
- if MatroskaTag::is_master(tag.id())? {
+ let tag = tag.unwrap();
+ if MatroskaTag::is_master(tag.id()).unwrap() {
eprintln!("{tag:?}");
}
- w.write_tag(&tag)?;
+ w.write_tag(&tag).unwrap();
}
- Ok(())
}
diff --git a/matroska/src/bin/mkvdump.rs b/matroska/src/bin/mkvdump.rs
index ead6ece..4db1223 100644
--- a/matroska/src/bin/mkvdump.rs
+++ b/matroska/src/bin/mkvdump.rs
@@ -6,18 +6,17 @@
use jellymatroska::{matroska::MatroskaTag, read::EbmlReader, unflatten::IterWithPos};
use std::{fs::File, io::BufReader};
-fn main() -> anyhow::Result<()> {
+fn main() {
env_logger::init_from_env("LOG");
let path = std::env::args().nth(1).unwrap();
- let mut r = EbmlReader::new(BufReader::new(File::open(path)?));
+ let mut r = EbmlReader::new(BufReader::new(File::open(path).unwrap()));
while let Some(tag) = r.next() {
- let tag = tag?;
+ let tag = tag.unwrap();
match tag {
MatroskaTag::SimpleBlock(_) => (), // println!("{} SimpleBlock", r.position),
MatroskaTag::Block(_) => (), // println!("{} Block", r.position),
_ => println!("{} {tag:?}", r.position),
}
}
- Ok(())
}
diff --git a/matroska/src/block.rs b/matroska/src/block.rs
index 676b042..275066e 100644
--- a/matroska/src/block.rs
+++ b/matroska/src/block.rs
@@ -4,7 +4,7 @@
Copyright (C) 2023 metamuffin <metamuffin.org>
*/
use crate::{read::ReadExt, write::write_vint};
-use anyhow::Result;
+use crate::Result;
use std::io::Cursor;
pub enum LacingType {
diff --git a/matroska/src/error.rs b/matroska/src/error.rs
new file mode 100644
index 0000000..02e487d
--- /dev/null
+++ b/matroska/src/error.rs
@@ -0,0 +1,19 @@
+use thiserror::Error;
+
+#[derive(Debug, Error)]
+pub enum Error {
+ #[error("invalid padding")]
+ InvalidPadding,
+ #[error("varint too long")]
+ VarintTooLong,
+ #[error("global tags dont provide any context")]
+ GlobalTagsAsContext,
+ #[error("invalid length of a exact size type")]
+ InvalidTypeLen,
+ #[error("invalid utf8")]
+ InvalidUTF8,
+ #[error("unknown id")]
+ UnknownID,
+ #[error("io: {0}")]
+ Io(std::io::Error),
+}
diff --git a/matroska/src/lib.rs b/matroska/src/lib.rs
index b86af44..b2d052c 100644
--- a/matroska/src/lib.rs
+++ b/matroska/src/lib.rs
@@ -4,6 +4,7 @@
Copyright (C) 2023 metamuffin <metamuffin.org>
*/
pub mod block;
+pub mod error;
pub mod matroska;
pub mod read;
pub mod size;
@@ -20,3 +21,6 @@ pub enum Master {
Start,
End,
}
+
+pub(crate) use error::Error;
+pub(crate) type Result<T> = core::result::Result<T, Error>;
diff --git a/matroska/src/read.rs b/matroska/src/read.rs
index e2bf15c..cb3e45e 100644
--- a/matroska/src/read.rs
+++ b/matroska/src/read.rs
@@ -3,8 +3,9 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2023 metamuffin <metamuffin.org>
*/
+use crate::error::Error;
+use crate::Result;
use crate::{matroska::MatroskaTag, size::EbmlSize, unflatten::IterWithPos, Master};
-use anyhow::{anyhow, bail, Result};
use log::{debug, warn};
use std::{
collections::VecDeque,
@@ -47,14 +48,14 @@ impl EbmlReader {
pub fn read_byte(&mut self) -> Result<u8> {
let mut b = [0u8];
- self.inner.read_exact(&mut b)?;
+ self.inner.read_exact(&mut b).map_err(Error::Io)?;
self.position += 1;
Ok(b[0])
}
pub fn read_buf(&mut self, size: impl Into<usize>) -> Result<Vec<u8>> {
let size = size.into();
let mut b = vec![0u8; size];
- self.inner.read_exact(&mut b)?;
+ self.inner.read_exact(&mut b).map_err(Error::Io)?;
self.position += size;
Ok(b)
}
@@ -62,7 +63,7 @@ impl EbmlReader {
let s = self.read_byte()?;
let len = s.leading_zeros() + 1;
if len > 8 {
- bail!("varint too long");
+ Err(Error::VarintTooLong)?
}
let mut value = s as u64;
value -= 1 << (8 - len);
@@ -77,7 +78,7 @@ impl EbmlReader {
}
pub fn read_utf8(&mut self, size: impl Into<usize>) -> Result<String> {
let b = self.read_buf(size)?;
- Ok(String::from_utf8(b)?)
+ Ok(String::from_utf8(b).map_err(|_| Error::InvalidUTF8)?)
}
pub fn read_tag_id(&mut self) -> Result<u64> {
let (value, len) = self.read_vint_len()?;
@@ -141,16 +142,16 @@ impl EbmlReader {
/// context should be the next expected tag, such that the stack can be derived from its path.
pub fn seek(&mut self, position: usize, context: MatroskaTag) -> Result<()> {
- let path = context
- .path()
- .ok_or(anyhow!("global tags dont give context"))?;
+ let path = context.path().ok_or(Error::GlobalTagsAsContext)?;
debug!(
"seeking to {position} with a context restored from path {:x?}",
path
);
self.queue.clear();
self.position = position;
- self.inner.seek(SeekFrom::Start(position as u64))?;
+ self.inner
+ .seek(SeekFrom::Start(position as u64))
+ .map_err(Error::Io)?;
self.stack = path
.iter()
.map(|id| StackTag { id: *id, end: None })
@@ -198,13 +199,13 @@ impl IterWithPos for EbmlReader {
}
pub trait ReadValue: Sized {
- fn from_buf(buf: &[u8]) -> anyhow::Result<Self>;
+ fn from_buf(buf: &[u8]) -> Result<Self>;
}
impl ReadValue for u64 {
- fn from_buf(buf: &[u8]) -> anyhow::Result<Self> {
+ fn from_buf(buf: &[u8]) -> Result<Self> {
if buf.len() > 8 {
- bail!("u64 too big")
+ Err(Error::InvalidTypeLen)?
}
let mut val = 0u64;
for byte in buf {
@@ -215,9 +216,9 @@ impl ReadValue for u64 {
}
}
impl ReadValue for i64 {
- fn from_buf(buf: &[u8]) -> anyhow::Result<Self> {
+ fn from_buf(buf: &[u8]) -> Result<Self> {
if buf.len() > 8 {
- bail!("i64 too big")
+ Err(Error::InvalidTypeLen)?
}
Ok(if buf[0] > 127 {
if buf.len() == 8 {
@@ -231,29 +232,29 @@ impl ReadValue for i64 {
}
}
impl ReadValue for f64 {
- fn from_buf(buf: &[u8]) -> anyhow::Result<Self> {
+ fn from_buf(buf: &[u8]) -> Result<Self> {
Ok(if buf.len() == 4 {
f32::from_be_bytes(buf.try_into().unwrap()) as f64
} else if buf.len() == 8 {
f64::from_be_bytes(buf.try_into().unwrap())
} else {
- bail!("float is not 4 or 8 bytes long");
+ Err(Error::InvalidTypeLen)?
})
}
}
impl ReadValue for Vec<u8> {
- fn from_buf(buf: &[u8]) -> anyhow::Result<Self> {
+ fn from_buf(buf: &[u8]) -> Result<Self> {
Ok(buf.to_vec())
}
}
impl ReadValue for String {
- fn from_buf(buf: &[u8]) -> anyhow::Result<Self> {
- Ok(String::from_utf8(Vec::from(buf))?)
+ fn from_buf(buf: &[u8]) -> Result<Self> {
+ Ok(String::from_utf8(Vec::from(buf)).map_err(|_| Error::InvalidUTF8)?)
}
}
impl ReadValue for Master {
- fn from_buf(_: &[u8]) -> anyhow::Result<Self> {
+ fn from_buf(_: &[u8]) -> Result<Self> {
panic!("master shall not be read like this")
}
}
@@ -266,14 +267,14 @@ pub trait ReadExt: Read {
impl<T: Read> ReadExt for T {
fn read_byte(&mut self) -> Result<u8> {
let mut b = [0u8];
- self.read_exact(&mut b)?;
+ self.read_exact(&mut b).map_err(Error::Io)?;
Ok(b[0])
}
fn read_vint_len(&mut self) -> Result<(u64, usize)> {
let s = self.read_byte()?;
let len = s.leading_zeros() + 1;
if len > 8 {
- bail!("varint too long");
+ Err(Error::VarintTooLong)?
}
let mut value = s as u64;
value -= 1 << (8 - len);
diff --git a/matroska/src/unflatten.rs b/matroska/src/unflatten.rs
index ee1a8d9..8f40819 100644
--- a/matroska/src/unflatten.rs
+++ b/matroska/src/unflatten.rs
@@ -4,7 +4,8 @@
Copyright (C) 2023 metamuffin <metamuffin.org>
*/
use crate::{matroska::MatroskaTag, Master};
-use anyhow::Result;
+use crate::Result;
+
pub trait IterWithPos {
type Item;
diff --git a/matroska/src/write.rs b/matroska/src/write.rs
index 0b3b167..fb56cb9 100644
--- a/matroska/src/write.rs
+++ b/matroska/src/write.rs
@@ -3,8 +3,9 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2023 metamuffin <metamuffin.org>
*/
+use crate::error::Error;
+use crate::Result;
use crate::{matroska::MatroskaTag, size::EbmlSize, Master};
-use anyhow::{bail, Result};
use log::debug;
use std::io::{Seek, Write};
@@ -19,7 +20,7 @@ impl<W: Write> EbmlWriter<W> {
}
pub fn write(&mut self, data: &[u8]) -> Result<()> {
- self.inner.write_all(data)?;
+ self.inner.write_all(data).map_err(Error::Io)?;
self.position += data.len();
Ok(())
}
@@ -33,7 +34,7 @@ impl<W: Write> EbmlWriter<W> {
let mut size = position - self.position;
match size {
0 => return Ok(()),
- 1 => bail!("this is sadly not possible"),
+ 1 => Err(Error::InvalidPadding)?,
_ => (),
}
size -= 1; // subtract tag size
@@ -63,7 +64,7 @@ impl<W: Write> EbmlWriter<W> {
pub fn write_vint(&mut self, i: u64) -> Result<()> {
if i > (1 << 56) - 1 {
- bail!("vint does not fit");
+ Err(Error::VarintTooLong)?
}
self.write_vint_len(i, vint_length(i))
}
@@ -172,21 +173,21 @@ impl WriteValue for u64 {
}
}
impl WriteValue for f64 {
- fn write_to(&self, w: &mut Vec<u8>) -> Result<(), anyhow::Error> {
+ fn write_to(&self, w: &mut Vec<u8>) -> Result<()> {
w.push(0x88);
w.extend_from_slice(&self.to_be_bytes());
Ok(())
}
}
impl WriteValue for Vec<u8> {
- fn write_to(&self, w: &mut Vec<u8>) -> Result<(), anyhow::Error> {
+ fn write_to(&self, w: &mut Vec<u8>) -> Result<()> {
write_vint(w, self.len() as u64)?;
w.extend_from_slice(self);
Ok(())
}
}
impl WriteValue for String {
- fn write_to(&self, w: &mut Vec<u8>) -> Result<(), anyhow::Error> {
+ fn write_to(&self, w: &mut Vec<u8>) -> Result<()> {
let sl = self.as_bytes();
write_vint(w, sl.len() as u64)?;
w.extend_from_slice(sl);
@@ -226,7 +227,7 @@ impl WriteValue for Master {
pub fn write_vint(w: &mut Vec<u8>, i: u64) -> Result<()> {
if i > (1 << 56) - 1 {
- bail!("vint does not fit");
+ Err(Error::VarintTooLong)?
}
let len = (64 - i.leading_zeros() as usize) / 7 + 1;
let mut bytes = i.to_be_bytes();