Commit Graph
8 Commits
Author SHA1 Message Date
Karim Jerbi 21c4d6ab41 fix(dwf): bound XML element depth before roxmltree and Canvas walk
Bug:
Loading a DWFx package recursed twice on untrusted input:
1. roxmltree's tokenizer (parse_element <-> parse_content) recurses once
   per element nesting level (present in versions 0.20 and 0.21) - a
   page or descriptor nested about 100k deep overflows the stack inside
   Document::parse, before any application code runs;
2. the XPS walk recursed once per nested Canvas with no limit - about
   10k levels overflowed the stack.
Either one aborts the process during ATTACH.

Reproduce:
1. Build a DWFx (zip) whose .fpage / descriptor.xml nests elements
   (e.g. Canvas) about 100,000 deep.
2. ATTACH it.
3. Before: STATUS_STACK_OVERFLOW (0xc00000fd) - process death; a test
   calling only roxmltree::Document::parse on the same bytes reproduces
   it, proving the dependency's tokenizer dies first.
4. After: the file is rejected before parse (a log::warn records "XML
   nests deeper than 256 levels ... document rejected"), or - for Canvas
   nesting between 65 and 256 - the page renders with the too-deep
   subtree skipped while siblings and the rest of the page stay.

Fix:
A linear depth scan (xml_depth_within, skipping comments, CDATA, PIs,
doctype subsets and quoted attribute values so their angle brackets
never count; it may over-reject malformed markup but must never
under-count) gates all three Document::parse sites at 256 levels - real
pages nest single digits - and walk caps Canvas nesting at 64 (continue
skips that subtree, siblings unaffected), matching the compound-file
walker's cap. Rejections are logged so a rejected depth is
distinguishable from a corrupt parse.
2026-09-30 19:15:49 +01:00
ramox81andClaude Opus 5.5 f7106c7d30 DGN underlays: global origin, stored extents, colour table display, 3D cells
- V8 models are placed relative to their global origin (model header).
- A V8 model's extent is the union of its elements' stored ranges; a V7
  model's text box is one text height tall.
- Files without a colour table use the standard DGN default table; colour
  255 is read from the table's background entry.
- Colours from a file's colour table follow the background: near-white
  colours swap with it, and over non-black backgrounds some shades drop a
  step.
- DGN contrast pulls towards a pivot taken from the model's own colours,
  after the fade, which is blended into the background first.
- Shared cells are read through their full 3D placement, so tilted
  instances and 3D definitions are drawn in plan.
- Deleted V8 elements are skipped; lines along the model's extent stay in
  the raster.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 11:58:47 +03:00
Hakan SevenandClaude Opus 5.5 0c1676e612 fix(underlay): bound how far DWF packages and DGN streams inflate
The DWF package reader, the DGN stream inflater and the new DGN
ExtendedColors scan each read a zlib/zip payload to its end, so a
crafted or corrupt file could inflate until memory ran out. Cap them:
1 GiB for a whole DWF package, 512 MiB per DGN stream, 4 MiB per
ExtendedColors record candidate - far above real files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:17:38 +03:00
Hakan Seven d9899be35e Merge pull request #1514 from ramox81/codex/dwf-dgn-underlays
Attach Underlay ribbon menu, DWF/DGN attach dialog, DGN true colours
2026-09-28 17:17:17 +03:00
ramox81andClaude Opus 5.5 5b6cbff5b2 Attach Underlay ribbon menu, DWF/DGN attach dialog, DGN true colours
- Insert > Reference: the PDF Attach button becomes an Attach Underlay menu
  (PDF / DWF / DGN); its face runs the last one chosen.
- DWFATTACH, DGNATTACH and ATTACH on a .dwf/.dwfx/.dgn open the Attach
  dialog for that kind: sheets or models with thumbnails (one chosen),
  placement, path type, file details with the sheet / model size, and for
  DGN the conversion units (sub units offer 1 / sub units per master as the
  scale).
- DGN V8 true colours come from the ExtendedColors record packed in the
  non-model attributes stream; the colour word's high part numbers them.
- A DGN model's extent includes each text's box (its length along the
  baseline and 1.5 x its height), as the reference sizes a model.
- DWFx text uses the family named in its embedded (deobfuscated) font.
- DWF contrast pivots at 0.73 once colours are turned over for a dark
  background.
- Hairline strokes are drawn solid one pixel wide, and underlay rasters are
  made at or below their size on screen so those lines stay unbroken.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:08:06 +03:00
Hakan SevenandClaude Opus 5.5 e26e0352b7 fix(underlay): malformed DWF and DGN files no longer crash or hang the reader
- W2D: a stream cut off right after an extended opcode's '(' sliced its
  body backwards and panicked.
- DGN V8: the compound-file header was indexed before its length was
  known (a short file with the signature panicked), the sector shift was
  taken on trust (0 or 1 underflowed `sector / 4 - 1` into an endless
  loop), and the DIFAT chain count was unbounded. The header must now be
  complete, the shift 9 or 12, and the chain no longer than the file.

Found fuzzing the #1514 readers with truncated and random input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:06:14 +03:00
ramox81andClaude Opus 5.5 56ecf786f1 DWF/DGN underlays: clipping, layers, text, 3D DGN, colours and zoom extents
- PDFOSNAP, DWFOSNAP and DGNOSNAP are separate; UOSNAP sets them all and
  reads 2 while they differ. Enable Snap switches the selected kind's.
- DWFCLIP / DGNCLIP clip their own kind with the kind's prompts and message;
  CLIP routes DWF and DGN underlays there; Enter at a corner asks again.
- The right-edge underlay tools show for DWF and DGN too (import is PDF
  only).
- Underlay layers: DGN levels (V8 level table, "Default" listed as "0"; V7
  used levels named from the level name table), hidden through the layer
  override data with the DGN placeholder string first; a plotted DWF has
  none.
- V8 colour read from its colour word (by level, index, or a true colour
  drawn as its nearest index); 3D V8 elements drawn in plan (lines, line
  strings, ellipses and arcs by their orientation, text); a model's extent
  includes its text.
- DWF 6 TrueType text (font, height, rotation from the font opcode) and DWFx
  glyph runs are drawn; the default W2D colour map is the measured one.
- Contrast pulls lightness towards a per-kind pivot as measured (PDF 0.5,
  DWF 0.243, DGN 0.65).
- Zoom extents includes raster images and underlays whose frames are hidden.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:10:01 +03:00
ramox81andClaude Opus 5.5 cb7860e50e DWF and DGN underlays: attach, display, snaps, frames and references
DWFATTACH / -DWFATTACH and DGNATTACH / -DGNATTACH attach a DWF / DWFx sheet
or a DGN (V7 or V8) model with the reference's prompts; ATTACH routes the
file types to them. The sheet or model is read into vector paths, drawn as a
transparent underlay raster (contrast, fade, monochrome and background
adjustment apply) and offers its geometry to object snaps. Definitions are
kept in ACAD_DWFDEFINITIONS / ACAD_DGNDEFINITIONS, the External References
palette lists and reloads them, and image textures get line-keeping mip
levels so thin underlay lines stay visible when zoomed out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:53:25 +03:00