@@ -20,11 +20,59 @@ use office2pdf::config::{ConvertOptions, Format};
2020// ---------------------------------------------------------------------------
2121
2222const DENYLIST : & [ & str ] = & [
23- // Fuzzer-generated corrupted file (invalid checksum)
23+ // ── DOCX — fuzzer-generated / corrupted zip structures ───────────
24+ "clusterfuzz-testcase-minimized-POIFuzzer-6709287337197568.docx" ,
25+ "clusterfuzz-testcase-minimized-POIXWPFFuzzer-4791943399604224.docx" ,
26+ "clusterfuzz-testcase-minimized-POIXWPFFuzzer-4959857092198400.docx" ,
27+ "clusterfuzz-testcase-minimized-POIXWPFFuzzer-4961551840247808.docx" ,
28+ "clusterfuzz-testcase-minimized-POIXWPFFuzzer-5166796835258368.docx" ,
29+ "clusterfuzz-testcase-minimized-POIXWPFFuzzer-5313273089884160.docx" ,
30+ "clusterfuzz-testcase-minimized-POIXWPFFuzzer-5564805011079168.docx" ,
31+ "clusterfuzz-testcase-minimized-POIXWPFFuzzer-5569740188549120.docx" ,
32+ "clusterfuzz-testcase-minimized-POIXWPFFuzzer-6061520554164224.docx" ,
33+ "clusterfuzz-testcase-minimized-POIXWPFFuzzer-6120975439364096.docx" ,
34+ "clusterfuzz-testcase-minimized-POIXWPFFuzzer-6442791109263360.docx" ,
2435 "clusterfuzz-testcase-minimized-POIXWPFFuzzer-6733884933668864.docx" ,
25- // Fuzzer-generated corrupted files
36+ // Crash reporter — corrupted zip
37+ "crash-517626e815e0afa9decd0ebb6d1dee63fb9907dd.docx" ,
38+ // Deeply nested table cells — stack overflow risk
39+ "deep-table-cell.docx" ,
40+ // Truncated archive — incomplete zip
41+ "truncated62886.docx" ,
42+ // ── PPTX — fuzzer-generated / corrupted zip structures ───────────
43+ "clusterfuzz-testcase-minimized-POIFuzzer-5205835528404992.pptx" ,
44+ "clusterfuzz-testcase-minimized-POIXSLFFuzzer-4838644450394112.pptx" ,
45+ "clusterfuzz-testcase-minimized-POIXSLFFuzzer-4986044400861184.pptx" ,
46+ "clusterfuzz-testcase-minimized-POIXSLFFuzzer-5463285576892416.pptx" ,
47+ "clusterfuzz-testcase-minimized-POIXSLFFuzzer-5471515212382208.pptx" ,
48+ "clusterfuzz-testcase-minimized-POIXSLFFuzzer-5611274456596480.pptx" ,
49+ "clusterfuzz-testcase-minimized-POIXSLFFuzzer-6071540680032256.pptx" ,
50+ "clusterfuzz-testcase-minimized-POIXSLFFuzzer-6254434927378432.pptx" ,
51+ "clusterfuzz-testcase-minimized-POIXSLFFuzzer-6372932378820608.pptx" ,
52+ "clusterfuzz-testcase-minimized-POIXSLFFuzzer-6435650376957952.pptx" ,
53+ // Corrupted archive (OOM / hang)
54+ "Divino_Revelado.pptx" ,
55+ // ── XLSX — fuzzer-generated / corrupted zip structures ───────────
56+ "clusterfuzz-testcase-minimized-POIFuzzer-5040805309710336.xlsx" ,
57+ "clusterfuzz-testcase-minimized-POIXSSFFuzzer-4828727001088000.xlsx" ,
58+ "clusterfuzz-testcase-minimized-POIXSSFFuzzer-5089447305609216.xlsx" ,
59+ "clusterfuzz-testcase-minimized-POIXSSFFuzzer-5185049589579776.xlsx" ,
2660 "clusterfuzz-testcase-minimized-POIXSSFFuzzer-5265527465181184.xlsx" ,
2761 "clusterfuzz-testcase-minimized-POIXSSFFuzzer-5937385319563264.xlsx" ,
62+ "clusterfuzz-testcase-minimized-POIXSSFFuzzer-6123461607817216.xlsx" ,
63+ "clusterfuzz-testcase-minimized-POIXSSFFuzzer-6419366255919104.xlsx" ,
64+ "clusterfuzz-testcase-minimized-POIXSSFFuzzer-6448258963341312.xlsx" ,
65+ "clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-5025401116950528.xlsx" ,
66+ "clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-5542865479270400.xlsx" ,
67+ "clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-5636439151607808.xlsx" ,
68+ "clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-6504225896792064.xlsx" ,
69+ "clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-6594557414080512.xlsx" ,
70+ // Crash reporters — corrupted zip
71+ "crash-274d6342e4842d61be0fb48eaadad6208ae767ae.xlsx" ,
72+ "crash-9bf3cd4bd6f50a8a9339d363c2c7af14b536865c.xlsx" ,
73+ // Corrupted / truncated archive
74+ "58616.xlsx" ,
75+ // ── XLSX — adversarial / OOM-inducing ────────────────────────────
2876 // XML billion-laughs attack PoCs
2977 "poc-xmlbomb.xlsx" ,
3078 "poc-xmlbomb-empty.xlsx" ,
@@ -35,6 +83,8 @@ const DENYLIST: &[&str] = &[
3583 "poc-shared-strings.xlsx" ,
3684 // Extreme dimensions stress test (OOM)
3785 "too-many-cols-rows.xlsx" ,
86+ // Hangs during conversion (CI timeout)
87+ "bug62181.xlsx" ,
3888] ;
3989
4090/// Returns `true` if the file should be skipped due to being on the denylist.
@@ -443,15 +493,32 @@ fn test_bulk_all_formats() {
443493/// and does not reject normal files.
444494#[ test]
445495fn test_denylist_filtering ( ) {
446- // Every entry in DENYLIST should be recognized
496+ // Every entry in DENYLIST should be recognized regardless of parent directory
447497 for name in DENYLIST {
448- let path = PathBuf :: from ( format ! ( "tests/fixtures/xlsx/poi /{name}" ) ) ;
498+ let path = PathBuf :: from ( format ! ( "tests/fixtures/any/dir /{name}" ) ) ;
449499 assert ! (
450500 is_denylisted( & path) ,
451501 "Expected {name} to be denylisted, but it was not"
452502 ) ;
453503 }
454504
505+ // Denylist should cover all three formats
506+ let docx_count = DENYLIST . iter ( ) . filter ( |n| n. ends_with ( ".docx" ) ) . count ( ) ;
507+ let pptx_count = DENYLIST . iter ( ) . filter ( |n| n. ends_with ( ".pptx" ) ) . count ( ) ;
508+ let xlsx_count = DENYLIST . iter ( ) . filter ( |n| n. ends_with ( ".xlsx" ) ) . count ( ) ;
509+ assert ! (
510+ docx_count >= 14 ,
511+ "Expected ≥14 DOCX entries, got {docx_count}"
512+ ) ;
513+ assert ! (
514+ pptx_count >= 10 ,
515+ "Expected ≥10 PPTX entries, got {pptx_count}"
516+ ) ;
517+ assert ! (
518+ xlsx_count >= 15 ,
519+ "Expected ≥15 XLSX entries, got {xlsx_count}"
520+ ) ;
521+
455522 // Normal files must not be denylisted
456523 let normal = PathBuf :: from ( "tests/fixtures/xlsx/poi/sample.xlsx" ) ;
457524 assert ! (
0 commit comments