88 lines
2.6 KiB
Rust
88 lines
2.6 KiB
Rust
pub const RENDER_IMAGE: u32 = 1 << 0;
|
|
pub const RENDER_VIDEO: u32 = 1 << 1;
|
|
pub const RENDER_AUDIO: u32 = 1 << 2;
|
|
pub const RENDER_MARKDOWN: u32 = 1 << 3;
|
|
pub const RENDER_TEXT: u32 = 1 << 4;
|
|
pub const RENDER_DOCUMENT: u32 = 1 << 5;
|
|
pub const RENDER_EXECUTABLE: u32 = 1 << 6;
|
|
pub const RENDER_DANGEROUS: u32 = 1 << 7;
|
|
pub const RENDER_NO_INLINE: u32 = 1 << 8;
|
|
|
|
const DANGEROUS_EXTENSIONS: &[&str] = &[
|
|
"exe", "scr", "bat", "cmd", "sh", "dll", "so", "dylib", "jar", "msi", "com", "app", "apk",
|
|
];
|
|
|
|
const DANGEROUS_MIME_TYPES: &[&str] = &[
|
|
"text/html",
|
|
"text/javascript",
|
|
"text/css",
|
|
"application/javascript",
|
|
"application/ecmascript",
|
|
];
|
|
|
|
pub fn detect_mime_type(data: &[u8], file_name: &str) -> String {
|
|
if let Some(kind) = infer::get(data) {
|
|
let mime = kind.mime_type();
|
|
if !mime.is_empty() && mime != "application/octet-stream" {
|
|
return mime.to_string();
|
|
}
|
|
}
|
|
mime_guess::from_path(file_name)
|
|
.first_or_octet_stream()
|
|
.to_string()
|
|
}
|
|
|
|
pub fn compute_render_flags(mime_type: &str, file_name: &str, data: &[u8]) -> u32 {
|
|
let mut flags = 0u32;
|
|
|
|
if mime_type.starts_with("image/") {
|
|
flags |= RENDER_IMAGE;
|
|
} else if mime_type.starts_with("video/") {
|
|
flags |= RENDER_VIDEO;
|
|
} else if mime_type.starts_with("audio/") {
|
|
flags |= RENDER_AUDIO;
|
|
} else if mime_type == "text/markdown"
|
|
|| file_name.ends_with(".md")
|
|
|| file_name.ends_with(".markdown")
|
|
{
|
|
flags |= RENDER_MARKDOWN | RENDER_TEXT;
|
|
} else if mime_type.starts_with("text/") {
|
|
flags |= RENDER_TEXT;
|
|
} else if mime_type == "application/pdf" || mime_type.starts_with("application/vnd.") {
|
|
flags |= RENDER_DOCUMENT;
|
|
}
|
|
|
|
if DANGEROUS_MIME_TYPES.contains(&mime_type) {
|
|
flags |= RENDER_DANGEROUS | RENDER_NO_INLINE;
|
|
}
|
|
|
|
let ext = file_name.rsplit('.').next().unwrap_or("").to_lowercase();
|
|
if DANGEROUS_EXTENSIONS.contains(&ext.as_str()) {
|
|
flags |= RENDER_EXECUTABLE | RENDER_DANGEROUS | RENDER_NO_INLINE;
|
|
}
|
|
|
|
if let Some(kind) = infer::get(data) {
|
|
let mime = kind.mime_type();
|
|
if mime == "application/x-executable"
|
|
|| mime == "application/x-msdownload"
|
|
|| mime == "application/x-pie-executable"
|
|
{
|
|
flags |= RENDER_EXECUTABLE | RENDER_DANGEROUS | RENDER_NO_INLINE;
|
|
}
|
|
}
|
|
|
|
if flags & (RENDER_EXECUTABLE | RENDER_DANGEROUS) != 0 {
|
|
flags |= RENDER_NO_INLINE;
|
|
}
|
|
|
|
flags
|
|
}
|
|
|
|
pub fn is_dangerous(flags: u32) -> bool {
|
|
flags & RENDER_DANGEROUS != 0
|
|
}
|
|
|
|
pub fn should_inline(flags: u32) -> bool {
|
|
flags & RENDER_NO_INLINE == 0
|
|
}
|