Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ impl FileValidator {
"application/vnd.openxmlformats-officedocument.wordprocessingml.document" | // .docx
"application/vnd.openxmlformats-officedocument.presentationml.presentation" | // .pptx
"application/vnd.ms-powerpoint" | // .ppt
// Some tooling (e.g. python-docx) emits OOXML zips with non-standard
// entry ordering, so `infer` reports `application/zip` instead of the
// specific OOXML mime. Pair this with the extension check in
// `is_compatible_type` to still reject random zips.
"application/zip" |
"application/octet-stream" // Generic binary
)
}
Expand All @@ -96,6 +101,9 @@ impl FileValidator {
detected == extension
|| (detected == "application/octet-stream" && self.is_supported_mime(extension))
|| (extension == "application/octet-stream" && self.is_supported_mime(detected))
// OOXML files are zips; trust the extension when content-detection only
// sees the underlying zip container.
|| (detected == "application/zip" && self.is_supported_mime(extension))
}
}

Expand Down
Binary file added tests/fixtures/test_document_rels_first.docx
Binary file not shown.
34 changes: 34 additions & 0 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,40 @@ async fn test_successful_docx_conversion() {
assert_eq!(&pdf_content[0..4], b"%PDF");
}

// docx files generated by python-docx (and other tooling) put _rels/.rels before
// [Content_Types].xml inside the zip, so `infer` falls back to application/zip rather
// than the OOXML mime. Validator must still accept these as long as the extension matches.
#[tokio::test]
async fn test_docx_with_nonstandard_zip_ordering() {
ensure_server_running();
wait_for_server_ready().await;
let client = reqwest::Client::new();

let file_path = get_test_file_path("test_document_rels_first.docx");
let file_content = fs::read(&file_path).expect("Failed to read fixture");

let form = multipart::Form::new()
.part(
"file_content",
multipart::Part::bytes(file_content)
.mime_str("application/octet-stream")
.unwrap()
.file_name("test_document_rels_first.docx"),
)
.text("file_name", "test_document_rels_first.docx");

let response = client
.post(format!("{}/convert2/pdf", TEST_SERVER_URL))
.multipart(form)
.send()
.await
.expect("Failed to make conversion request");

assert_eq!(response.status(), 200);
let pdf_content = response.bytes().await.expect("Failed to read PDF response");
assert_eq!(&pdf_content[0..4], b"%PDF");
}

#[tokio::test]
async fn test_successful_xlsx_conversion() {
ensure_server_running();
Expand Down