mindeng / nom-exif

Exif/metadata parsing library written in pure Rust, both image (jpeg/heif/heic/jpg/tiff/raf etc.) and video/audio (mov/mp4/3gp/webm/mkv/mka, etc.) files are supported.
https://crates.io/crates/nom-exif
MIT License
47 stars 7 forks source link

Freeze when checking broken file #19

Open qarmin opened 4 days ago

qarmin commented 4 days ago

Code

fn check_file(path: &str) {
    let content = match fs::read(&path) {
        Ok(content) => content,
        Err(e) => {
            println!("{e}");
            return;
        }
    };
    println!("Checking file: {path}");

    let mut parser = MediaParser::new();

    // Parse unseekable
    let reader = Cursor::new(&content);
    let Ok(ms) = MediaSource::unseekable(reader) else {
        return ;
    };
    let iter: Result<ExifIter, _> = parser.parse(ms);
    if let Ok(iter) = iter {
        let _ = iter.parse_gps_info();
        for i in iter {
            let s = i;
            s.tag_code();
            s.get_value();
            let _ = s.get_result();
            s.tag();
            s.ifd_index();
            s.has_value();
        }
    }

    let reader = Cursor::new(&content);
    let Ok(ms) = MediaSource::unseekable(reader) else {
        return ;
    };
    let _: Result<TrackInfo, _> = parser.parse(ms);

    // Parse seekable
    let reader = Cursor::new(&content);
    let Ok(ms) = MediaSource::seekable(reader) else {
        return ;
    };
    let iter: Result<ExifIter, _> = parser.parse(ms);
    if let Ok(iter) = iter {
        let _ = iter.parse_gps_info();
        for i in iter {
            let s = i;
            s.tag_code();
            s.get_value();
            let _ = s.get_result();
            s.tag();
            s.ifd_index();
            s.has_value();
        }
    }

    let reader = Cursor::new(&content);
    let Ok(ms) = MediaSource::seekable(reader) else {
        return ;
    };
    let _: Result<TrackInfo, _> = parser.parse(ms);
}

freezes here

#0  core::sync::atomic::atomic_load<usize> (order=core::sync::atomic::Ordering::Relaxed, dst=<optimized out>)
    at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/sync/atomic.rs:3310
#1  core::sync::atomic::AtomicUsize::load (self=<optimized out>) at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/sync/atomic.rs:2418
#2  tracing_core::metadata::LevelFilter::current () at /home/rafal/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tracing-core-0.1.32/src/metadata.rs:698
#3  nom_exif::exif::exif_iter::{impl#6}::next (self=0x7fffffffcd20) at src/exif/exif_iter.rs:390
#4  0x00005555555b99df in core::iter::traits::iterator::Iterator::try_fold<nom_exif::exif::exif_iter::ExifIter, (), core::iter::traits::iterator::Iterator::find::check::{closure_env#0}<nom_exif::exif::exif_iter::ParsedExifEntry, nom_exif::exif::exif_iter::{impl#2}::parse_gps_info::{closure_env#0}>, core::ops::control_flow::ControlFlow<nom_exif::exif::exif_iter::ParsedExifEntry, ()>> (self=0x7fffffffcd20, init=<optimized out>, f=...) at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/iter/traits/iterator.rs:2404
#5  core::iter::traits::iterator::Iterator::find<nom_exif::exif::exif_iter::ExifIter, nom_exif::exif::exif_iter::{impl#2}::parse_gps_info::{closure_env#0}> (self=0x7fffffffcd20)
    at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/iter/traits/iterator.rs:2875
#6  nom_exif::exif::exif_iter::ExifIter::parse_gps_info (self=<optimized out>) at src/exif/exif_iter.rs:155
#7  0x00005555555a72c9 in nom_exif::check_file (path=...) at src/main.rs:47
#8  0x00005555555a6a9e in nom_exif::main () at src/main.rs:24

file - timeout-7c28bc950777630fd2d6d460c7b3285b8be1ced0.zip

mindeng commented 12 hours ago

Got it! I’ll find time to analyze it as soon as possible! Thank you for your feedback!