Skip to content

Changelog

Changelog

Unreleased

Features

  • add an anydoc backend and make it the default for document conversion (#297)
  • DOCX, PPTX, XLSX, and CSV now convert through anydoc, a required dependency, and backends.default is anydoc, so .doc, .xls, .ppt, .odt, .ods, .odp, .rtf, and .epub convert without extra configuration.
  • PDF stays on the native backend: anydoc exposes no document model for PDF, so it cannot extract page images, ## Page N headings, or the page_count frontmatter derived from them, and it has no OCR for scanned PDFs. Set backends.pdf: anydoc to use anydoc for PDFs anyway.
  • JSON, YAML, and image files keep the native backends; HTML keeps markitdown.
  • Images embedded in Word, PowerPoint, Excel, OpenDocument, and EPUB files are extracted into the note's media folder and embedded as wikilinks at the position they held in the source document. anydoc's markdown contains no reference to an embedded image, so the embeds are spliced in by aligning its markdown blocks with the document model that carries the images; if the two stop lining up, the remaining images are embedded at the end of the note.
  • extraction.xlsx_max_rows_per_sheet applies to the native xlsx backend only. anydoc reads every row and the option is reported as ignored; set backends.xlsx: native to cap the rows read per sheet.

Bug Fixes

  • report a backend's ignored config options once per configuration instead of once per file, so batch runs no longer repeat the same warning for every document (#297)
  • keep anydoc images embedded inline after ordered lists, nested lists, and referenced link targets. anydoc renders a list marker (1., - c., - iii.) into text the document model does not carry, puts a blank line before nested items, and emits an <a id="..."></a> block of its own for a referenced footnote target. Each of those stopped block alignment, which left every image after it appended at the end of the note (#297)
  • report a backend whose converter is not installed as missing. Backends import their converter lazily, so doctor reported anydoc, markitdown, and docling as available whenever the wrapper module imported — which it always does. doctor now probes the dependency each backend declares (#297)

Security

  • pin soupsieve >=2.8.4 for CVE-2026-49477/49476: ReDoS and memory exhaustion (#266)

1.3.3 (2026-09-11)

Bug Fixes

  • replace O(n²) wikilink deduplication loop with single-pass collect-and-join (#339) (37100d4)

1.3.2 (2026-09-07)

Bug Fixes

  • bump pypdf minimum to >=6.16.1 for CVE-2026-84309/84310/84311 (#333) (09fb303)

1.3.1 (2026-08-28)

Bug Fixes

  • bump pip lower bound to >=26.2 for PYSEC-2026-3721 (#319) (15ca94d)
  • narrow bare except Exception to specific types in timeout.py (#323) (9a076e8)

1.3.0 (2026-08-10)

Features

  • default document conversion to the anydoc backend (a7e0d25)
  • embed anydoc images inline and keep PDFs on the native backend (d5d3ce9)

Bug Fixes

  • keep anydoc images inline across lists and renderer-only blocks (4a41d4b)
  • report a backend whose converter is not installed as missing (747f222)

Documentation

  • list the formats anydoc adds and record the placement fixes (7c10811)

1.2.2 (2026-08-05)

Bug Fixes

  • bump pypdf lower bound to >=6.13.3 for GHSA-jm82-fx9c-mx94 (#238) (03fd94e)
  • pin pyasn1 >=0.6.4 for PYSEC-2026-3455/3456/3457 DoS vulnerabilities (#281) (17ecb78)
  • pin pygments >=2.20.0 for PYSEC-2026-2987 vulnerability (#289) (8c68c9f)
  • pin pymdown-extensions >=11.0.0 for CVE-2026-61632 b64 path traversal (#283) (bd77ef7)
  • pin pypdf >=6.14.2 for CVE-2026-59935/59936/59937/59938 DoS vulnerabilities (#282) (6ee9a5f)
  • pin requests >=2.33.0 for PYSEC-2026-2275 vulnerability (#290) (85dc238)
  • pin soupsieve >=2.8.4 for CVE-2026-49477/49476 ReDoS and memory exhaustion (#266) (ae37ca1)
  • pin torch >=2.13.0 for PYSEC-2025-194 deserialization vulnerability (#291) (da1e9c3)
  • remove type: ignore suppressions in native_pptx.py (e613f35)
  • remove type: ignore suppressions in native_pptx.py (#246) (c54c3c6)
  • replace pickle IPC with JSON to prevent code execution from compromised child (#287) (d396795)
  • stream-verify ZIP entry sizes to prevent zip bomb via falsified metadata (#254) (4d7c7a0)
  • upgrade cryptography to >=48.0.1 for GHSA-537c-gmf6-5ccf (#237) (80d78f9)
  • upgrade Pillow >=12.3.0 for PYSEC-2026-2253/2254/2255/2256/2257 (#265) (c84b3ed)

1.2.1 (2026-06-16)

Bug Fixes

  • add missing isolation arg to TestDecompressionBombGuard extract() calls (592a115)
  • add missing isolation arg to TestDecompressionBombGuard tests (b830426)
  • bump pypdf lower bound to >=6.12.0 for CVE-2026-48155/48156 (#232) (c3189e7)
  • pass missing isolation argument in TestDecompressionBombGuard tests (#228) (1ed867b)

1.2.0 (2026-06-11)

Features

  • extraction guards — size limit at entry, process isolation, public config API (1f24d66)
  • extraction guards — size limit at entry, process isolation, public config API (1.2.0) (ecce207)

Bug Fixes

  • replace assert isinstance() with explicit runtime type checks in registry.py (#206) (2ee0ee8)
  • replace assert isinstance() with explicit runtime type guards in registry.py (13e27aa)
  • replace assert isinstance() with explicit runtime type guards in registry.py (#206) (c1d2e85)

1.2.0 (2026-06-11)

Features

  • enforce max_file_size_mb at the extract_file/extract_text entry points — oversized files raise ExtractionError instantly before backend dispatch, instead of running into the extraction timeout when callers bypass discover_files
  • add config_from_overrides() public API: build an ImportConfig from a partial overrides dict deep-merged onto the bundled defaults (the supported path for library consumers such as m365-extract)
  • add extraction.isolation config ("thread" | "process", default "thread"): process mode runs each extraction in a separate spawned process that is killed on timeout — true cancellation and memory isolation for long-running daemons
  • include the source file size in ExtractionTimeoutError messages alongside label, timeout, and path

Bug Fixes

  • process isolation enforces the deadline on every parent-side wait: receiving the payload is bounded by a watchdog that kills a stalled child, and the worker is reaped (bounded join, then kill) on success, error, and interrupt paths — a child kept alive by a leftover non-daemon thread can no longer block the caller indefinitely
  • worker exceptions that cannot survive the pickle round-trip are reported as ExtractionError with the original message, instead of escaping as a raw TypeError that aborted CLI batch runs; payloads that still fail to unpickle parent-side are wrapped defensively
  • the extraction worker process is no longer daemonic, so backends may spawn their own worker processes (e.g. docling's torch DataLoader)
  • stat() failures in the entry-point size guard (file vanished between discovery and extraction) raise ExtractionError, keeping the ObsidianImportError contract so CLI batch runs print FAIL and continue
  • the "process died without a result" error now explains the if __name__ == "__main__": guard required for script consumers under spawn

1.1.2 (2026-05-20)

Bug Fixes

  • call _cleanup_temp_source in copy_media_files to remove temp dirs (6682e90)
  • clean up temp dirs created by save_media_to_temp after media copy (#176) (026e76c)
  • sanitize PDF form field values against markdown injection (#171) (9b22822)
  • serialize Image.MAX_IMAGE_PIXELS mutation with threading.Lock (#194) (3b389c6)

Documentation

  • add cleanup side-effect to copy_media_files docstring and CHANGELOG entry (152709b)

1.1.1 (2026-05-11)

Bug Fixes

  • scope Image.MAX_IMAGE_PIXELS mutation to _process_image_bytes lifetime (#163) (037974c)

1.1.0 (2026-04-28)

Features

  • add .html as a first-class backend config key (4602f1b)
  • add .html as a first-class backend config key (e64b82f)

Bug Fixes

  • add decompression bomb guard with configurable image_max_pixels (#113) (bb840be)
  • bump Pillow lower bound to >=12.2 for CVE-2026-40192 (#127) (35f9167)
  • bump pypdf lower bound to 6.10.2 for DoS CVE fixes (e49878e), closes #126
  • correct misleading native extensions list and add .htm dispatch test (afa2521)
  • scope try/except per XObject iteration in _extract_page_images (#120) (2d8a820)

[Unreleased]

Bug Fixes

  • clean up temp dirs created by save_media_to_temp after media copy (#176)

Security

  • serialize Image.MAX_IMAGE_PIXELS mutation with threading.Lock for thread safety (#194)
  • track PYSEC-2026-3804 in accelerate (transitive via docling): path traversal + DoS via crafted checkpoint indexes (CVE-2026-69112), no fix available as of 2026-09-14 (#345)
  • track PYSEC-2025-217 in transformers (transitive via docling): X-CLIP checkpoint deserialization RCE, no fix available as of 2026-06-29 (#251)
  • bump pip floor to >=26.1 for CVE-2026-6357 (#183)
  • bump pytest floor to >=9.0.3 for CVE-2025-71176 (#184)
  • pin cryptography >=46.0.7 for CVE-2026-39892 (#181)
  • drop direct twisted dep to remove CVE-2026-42304 exposure (#185)
  • track CVE-2026-3219 in pip (build-only dep, no fix available yet) (#182)
  • track PYSEC-2026-139 in torch (transitive via docling, deserialization vuln, no fix available) (#200)
  • track CVE-2025-3000 in torch (transitive via docling, memory corruption in torch.jit.script, no fix available) (#250)
  • bump pypdf >=6.10.2 to address multiple High-severity DoS CVEs (CVE-2026-40260, GHSA-jj6c-8h6c-hppx, GHSA-4pxv-j86v-mhcw, GHSA-7gw9-cf7v-778f, GHSA-x284-j5p8-9c5p) (#126)

1.0.4 (2026-04-13)

Bug Fixes

  • add extract_images parameter to config_for_backend (#85) (fbc9def)
  • bump pypdf >=6.9.2 to address CVE-2026-33699 infinite loop DoS (#94) (67e2286)
  • correct exception type in native_pdf.py and add missing test (cdcd0d3)
  • decompose _extract_page_images to reduce cyclomatic complexity (#102) (a4547bd)
  • extract shared attempt_save_image helper to eliminate DRY violation (#99) (964354d)
  • replace hand-rolled YAML escaping with PyYAML serializer (#75) (37535e0)
  • resolve merge conflict — reapply exception narrowing to refactored code (f8d8165)
  • validate image bytes size and format before Pillow processing (#74) (ba5be45)

1.0.3 (2026-03-27)

Bug Fixes

  • address security and code quality issues (#14, #37, #59, #63, #64) (4845e67)
  • address security and code quality issues (#14, #37, #59, #63, #64) (9c9fb18)
  • bump pypdf >=6.9.1 to address CVE-2026-33123 DoS vulnerability (#55) (b9e2a8c)
  • strengthen type annotations and simplify docling availability check (00f951b)
  • strengthen type annotations and simplify docling check (86dfa39)

Documentation

  • sync documentation with codebase (f797c3d)

1.0.2 (2026-03-20)

Bug Fixes

  • eliminate hidden mutation side-effect in _match_image_ref (#41) (e6dc690)

1.0.1 (2026-03-17)

Bug Fixes

  • add upper-bound version pins for markitdown and docling optional deps (ef63111), closes #30
  • add upper-bound version pins for markitdown and docling optional… (4471a29)
  • bump Pillow to >=12.1,<13 to address CVE-2026-25990 (#29) (ee2cc8e)
  • move stdlib xml.etree.ElementTree import to TYPE_CHECKING block (#17) (829cea3)
  • regenerate pixi.lock in release-please PR (c4f6c76)
  • regenerate pixi.lock in release-please PR (1ea1ccb)

1.0.0 (2026-03-12)

  • feat: embedded media extraction for PDF, DOCX, PPTX (per-document media folders with wikilinks)
  • feat: config_for_backend() convenience API for quick single-backend configuration
  • feat: MediaConfig for image extraction settings (format, max dimension, enable/disable)
  • deps: added Pillow>=10.0,<12
  • BREAKING: ImportConfig requires media: MediaConfig field
  • BREAKING: backend extract() returns ExtractionResult (with .markdown and .media_files) instead of str

0.2.0 (2026-03-10)

  • Native backends for CSV, JSON, YAML, and image files
  • Image embedding: generates Obsidian ![[filename]] wikilinks and copies source images to vault
  • Pass-through mode: copy files as-is without extraction (configurable by extension, glob, regex)
  • Per-extension backend configuration (backends.csv, backends.json, backends.yaml, backends.image)
  • OutputConflictError exception for destination file conflicts

0.1.0 (2026-03-09)

Initial release.

  • Native backends: PDF (pdfplumber+pypdf), DOCX (defusedxml), PPTX (python-pptx), XLSX (openpyxl)
  • Optional backends: markitdown (fallback), docling (high-quality)
  • Config-driven backend selection per file type
  • Glob-based file discovery with exclude patterns
  • Obsidian-flavored markdown output with YAML frontmatter
  • Click CLI: convert, discover, batch, doctor
  • YAML configuration with deep-merge defaults