aboutsummaryrefslogtreecommitdiff
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
parent4a0f08126d80dc589e3c97bf0a07571b8b828a74 (diff)
downloadjellything-7cba183debcf2cefd90b4c1e7a630fb0c2152d06.tar
jellything-7cba183debcf2cefd90b4c1e7a630fb0c2152d06.tar.bz2
jellything-7cba183debcf2cefd90b4c1e7a630fb0c2152d06.tar.zst
(semi-)proper error handling in matroska
-rw-r--r--Cargo.lock10
-rw-r--r--ebml_derive/src/lib.rs14
-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
-rw-r--r--remuxer/src/import/mod.rs5
-rw-r--r--remuxer/src/import/seek_index.rs7
13 files changed, 88 insertions, 58 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5422a63..89f4b5a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1257,10 +1257,10 @@ dependencies = [
name = "jellymatroska"
version = "0.1.0"
dependencies = [
- "anyhow",
"ebml_derive",
"env_logger",
"log",
+ "thiserror",
]
[[package]]
@@ -2389,18 +2389,18 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.40"
+version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
+checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.40"
+version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
+checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
dependencies = [
"proc-macro2",
"quote",
diff --git a/ebml_derive/src/lib.rs b/ebml_derive/src/lib.rs
index 18a43a9..5836747 100644
--- a/ebml_derive/src/lib.rs
+++ b/ebml_derive/src/lib.rs
@@ -119,16 +119,16 @@ pub fn define_ebml(ts: TokenStream) -> TokenStream {
pub fn id(&self) -> u64 {
match self { #(#id_match),* }
}
- pub fn is_master(id: u64) -> anyhow::Result<bool> {
- Ok(match id { #(#is_master_match),*, _ => anyhow::bail!("unknown id") })
+ pub fn is_master(id: u64) -> crate::Result<bool> {
+ Ok(match id { #(#is_master_match),*, _ => return Err(crate::Error::UnknownID) })
}
- pub fn construct_master(id: u64, kind: Master) -> anyhow::Result<Self> {
- Ok(match id { #(#cons_master_match),*, _ => anyhow::bail!("unknown id") })
+ pub fn construct_master(id: u64, kind: Master) -> crate::Result<Self> {
+ Ok(match id { #(#cons_master_match),*, _ => return Err(crate::Error::UnknownID) })
}
- pub fn parse(id: u64, data: &[u8]) -> anyhow::Result<Self> {
- Ok(match id { #(#parse_match),*, _ => anyhow::bail!("unknown id or master") })
+ pub fn parse(id: u64, data: &[u8]) -> crate::Result<Self> {
+ Ok(match id { #(#parse_match),*, _ => return Err(crate::Error::UnknownID) })
}
- pub fn write(&self, w: &mut Vec<u8>) -> anyhow::Result<()> {
+ pub fn write(&self, w: &mut Vec<u8>) -> crate::Result<()> {
match self { #(#write_match),* }
}
}
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();
diff --git a/remuxer/src/import/mod.rs b/remuxer/src/import/mod.rs
index 309357b..ade1fe0 100644
--- a/remuxer/src/import/mod.rs
+++ b/remuxer/src/import/mod.rs
@@ -32,7 +32,9 @@ pub fn import_metadata(input: &mut EbmlReader) -> Result<MatroskaMetadata> {
let item = match item {
Ok(item) => item,
Err(e) => {
- warn!("{e}");
+ if !matches!(e, jellymatroska::error::Error::Io(_)) {
+ warn!("{e}");
+ }
break;
}
};
@@ -129,6 +131,7 @@ fn import_read_segment(segment: &mut Unflatten) -> Result<MatroskaMetadata> {
}
}
}
+ MatroskaTag::Crc32(_) => {}
_ => debug!("(rst) tag ignored: {item:?}"),
}
}
diff --git a/remuxer/src/import/seek_index.rs b/remuxer/src/import/seek_index.rs
index efd2a78..ca1ca1e 100644
--- a/remuxer/src/import/seek_index.rs
+++ b/remuxer/src/import/seek_index.rs
@@ -36,7 +36,9 @@ pub fn import_seek_index(input: &mut EbmlReader) -> Result<BTreeMap<u64, SeekInd
let item = match item {
Ok(item) => item,
Err(e) => {
- warn!("{e}");
+ if !matches!(e, jellymatroska::error::Error::Io(_)) {
+ warn!("{e}");
+ }
break;
}
};
@@ -110,7 +112,8 @@ fn import_seek_index_segment(
let block = Block::parse(&buf)?;
trace!(
"simple block: track={} tso={}",
- block.track, block.timestamp_off
+ block.track,
+ block.timestamp_off
);
trace!("{pts} {}", block.timestamp_off);
seek_index