use crate::signatures::common::{SignatureError, SignatureResult};
pub const DESCRIPTION: &str = "PDF document";
pub fn pdf_magic() -> Vec<Vec<u8>> {
vec![b"%PDF-1.".to_vec()]
}
pub fn pdf_parser(file_data: &[u8], offset: usize) -> Result<SignatureResult, SignatureError> {
const MIN_PDF_SIZE: usize = 16;
const NEWLINE_OFFSET: usize = 8;
const MINOR_NUMBER_OFFSET: usize = 7;
const ASCII_ZERO: u8 = 0x30;
const ASCII_NINE: u8 = 0x39;
const ASCII_NEWLINE: u8 = 0x0A;
const ASCII_PERCENT: u8 = 0x25;
const ASCII_CARRIGE_RETURN: u8 = 0x0D;
let mut result = SignatureResult {
description: DESCRIPTION.to_string(),
offset,
size: 0,
..Default::default()
};
let newline_characters: Vec<u8> = vec![ASCII_NEWLINE, ASCII_CARRIGE_RETURN];
let pdf_header_start = offset;
let pdf_header_end = pdf_header_start + MIN_PDF_SIZE;
if let Some(pdf_header) = file_data.get(pdf_header_start..pdf_header_end) {
let version_minor: u8 = pdf_header[MINOR_NUMBER_OFFSET];
if (ASCII_ZERO..=ASCII_NINE).contains(&version_minor) {
result.description = format!(
"{}, version 1.{}",
result.description,
version_minor - ASCII_ZERO
);
for byte in pdf_header[NEWLINE_OFFSET..].iter().copied() {
if newline_characters.contains(&byte) {
continue;
} else if byte == ASCII_PERCENT {
return Ok(result);
} else {
break;
}
}
}
}
Err(SignatureError)
}