diff options
Diffstat (limited to 'support/pkgcheck/src/filemagic.rs')
-rw-r--r-- | support/pkgcheck/src/filemagic.rs | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/support/pkgcheck/src/filemagic.rs b/support/pkgcheck/src/filemagic.rs index 40edd18351..2ae8bfae6e 100644 --- a/support/pkgcheck/src/filemagic.rs +++ b/support/pkgcheck/src/filemagic.rs @@ -19,16 +19,23 @@ use unicode_bom::Bom; // - https://filesignatures.net/ // - https://github.com/7h3rAm/cigma/blob/master/cigma/magicbytes.json + +#[derive(Debug, PartialEq)] +pub enum LineEnding { + LF, + CR, + CRLF, + MIXED(usize, usize, usize), +} + #[derive(Debug, PartialEq)] pub enum Mimetype { Binary, - Script, - ScriptCRLF, + Script(LineEnding), Pdf, Archive, Zip, - Text, - TextCRLF, + Text(LineEnding), Data, Unknown, BlockDevice, @@ -42,6 +49,7 @@ pub enum Mimetype { BOM(Bom), } + pub struct Filetype { buffer: Vec<u8>, } @@ -91,7 +99,7 @@ fn _is_crlf(buffer: &[u8], len: usize) -> bool { false } -fn is_crlf(buffer: &[u8], len: usize) -> bool { +fn is_crlf(buffer: &[u8], len: usize) -> LineEnding { let mut seen_cr = false; let mut n_crlf = 0; let mut n_lf = 0; @@ -114,18 +122,18 @@ fn is_crlf(buffer: &[u8], len: usize) -> bool { seen_cr = *c == CR; } + // println!("LF / CR / CRLF: {} / {} / {}", n_lf, n_cr, n_crlf); + // println!("cr: {}, lf: {}, crlf: {}", n_cr, n_lf, n_crlf); // if (n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) // --> no line terminators - if n_crlf == 0 && n_cr == 0 && n_lf == 0 { - return false; - } - if n_crlf > 0 || n_cr > 0 { - return true; + match (n_cr, n_lf, n_crlf) { + (0, 0, z) if z > 0 => LineEnding::CRLF, + (x, 0, 0) if x > 0 => LineEnding::CR, + (0, y, 0) if y > 0 => LineEnding::LF, + (x, y, z) => LineEnding::MIXED(x, y, z), } - - false } impl Filetype { @@ -175,10 +183,6 @@ impl Filetype { return Ok(Mimetype::Pdf); } - if bytes_read >= 5 && &self.buffer[0..5] == b"<?php" { - return Ok(Mimetype::Script); - } - // rtf document if bytes_read >= 6 && &self.buffer[0..6] == b"\x7B\x5C\x72\x74\x66\x31" { return Ok(Mimetype::Data); @@ -224,27 +228,36 @@ impl Filetype { } } + //println!("Filename: {}", fname); + let crlf = is_crlf(&self.buffer, bytes_read); + //println!("{:?}", crlf); if bytes_read >= 5 && (self.buffer.starts_with(b"#!") || self.buffer.starts_with(b"<?php")) { - if crlf { - return Ok(Mimetype::ScriptCRLF); - } else { - return Ok(Mimetype::Script); - } + return Ok(Mimetype::Script(crlf)); } + // recognize files as script files by file endings let is_script = Regex::new(r"\.(csh|ksh|py|pl|sh|tcsh)$") .unwrap() .is_match(fname.as_bytes()); - match (crlf, is_script) { - (false, false) => Ok(Mimetype::Text), - (true, false) => Ok(Mimetype::TextCRLF), - (false, true) => Ok(Mimetype::Script), - (true, true) => Ok(Mimetype::ScriptCRLF), + //println!("le/is_script: {:?}, {:?}", crlf, is_script); + if is_script { + Ok(Mimetype::Script(crlf)) + } else { + Ok(Mimetype::Text(crlf)) } + // match (crlf, is_script) { + // (LineEnding::LF, false) => Ok(Mimetype::Text(LineEnding::LF)), + // (LineEnding::CR, false) => Ok(Mimetype::Text(LineEnding::CR)), + // (LineEnding::CRLF, false) => Ok(Mimetype::Text(LineEnding::CRLF)), + // (LineEnding::LF, true) => Ok(Mimetype::Script(LineEnding::LF)), + // (LineEnding::CR, true) => Ok(Mimetype::Script(LineEnding::CR)), + // (LineEnding::CRLF, true) => Ok(Mimetype::Script(LineEnding::CRLF)), + // (_, _) => Ok(Mimetype::Text(LineEnding::LF)), + // } } } @@ -388,8 +401,8 @@ fn test_filetype() { // analyze() says TextCRLF //assert!(ft.analyze("tests_filemagic/musterlogo.pdf").ok() == Some(Mimetype::Script)); - assert!(ft.analyze("tests_filemagic/x.pl").ok() == Some(Mimetype::Script)); - assert!(ft.analyze("tests_filemagic/main.php").ok() == Some(Mimetype::Script)); + assert!(ft.analyze("tests_filemagic/x.pl").ok() == Some(Mimetype::Script(LineEnding::LF))); + assert!(ft.analyze("tests_filemagic/main.php").ok() == Some(Mimetype::Script(LineEnding::LF))); assert!(ft.analyze("tests_filemagic/test.7z").ok() == Some(Mimetype::Archive)); assert!(ft.analyze("tests_filemagic/x.tgz").ok() == Some(Mimetype::Archive)); @@ -404,7 +417,7 @@ fn test_filetype() { assert!(ft.analyze("tests_filemagic/empty.zip").ok() == Some(Mimetype::Zip)); - assert!(ft.analyze("tests_filemagic/README").ok() == Some(Mimetype::Text)); + assert!(ft.analyze("tests_filemagic/README").ok() == Some(Mimetype::Text(LineEnding::MIXED(0,0,0)))); // assert!(ft.analyze("tests_filemagic/README1").ok() == Some(Mimetype::Text)); assert!(ft.analyze("tests_filemagic/cp").ok() == Some(Mimetype::Binary)); @@ -418,5 +431,5 @@ fn test_filetype() { assert!(ft.analyze("tests_filemagic/chap5.rtf").ok() == Some(Mimetype::Data)); assert!(ft.analyze("tests_filemagic/commons-math.jar").ok() == Some(Mimetype::Data)); - assert!(ft.analyze("tests_filemagic/8stbu11h.htm").ok() == Some(Mimetype::TextCRLF)); + assert!(ft.analyze("tests_filemagic/8stbu11h.htm").ok() == Some(Mimetype::Text(LineEnding::MIXED(0,1,8710)))); } |