* DWG open: stop runaway conversions early, name the limit (#57)
"file too large" was the DXF reader's 50,000,000 group-code cap (MAX_TAGS),
not a file-size limit. For a DWG it was only checked at the very end: after
acadrust had read the whole file, written all of its DXF text into one Vec,
the text had been copied again for decoding, and 50 million tags had been
parsed. A real 10 MB DWG is nowhere near the cap (a synthetic 10 MB AC1024
file is 3.7 million group codes and opens in about 2 s). A damaged file, or
objects the DWG reader misreads, can be: acadrust caps every count at 100,000
and reads zeros past the end of the data, so one desynchronised object becomes
a polyline with 100,000 vertices. A fuzzed 0.25 MB AC1024 file made it write
11 GB of DXF.
- cadcraft-dwg: Limits { max_dwg_bytes: 512 MB, max_dxf_bytes: 1 GB }. The DWG
size is checked before the reader runs; the DXF is streamed into a writer
that fails as soon as it passes the limit, so the conversion stops there
instead of filling memory. Both errors give actual and allowed sizes. The
input is no longer copied, and the DXF writer also runs under catch_unwind.
- cadcraft-dxf: TooLarge { tags, limit } says "drawing too large: N DXF group
codes, more than the 50000000 CADCraft reads". For ASCII the count comes
from the line count before any decoding or tag allocation. Valid UTF-8 text
is borrowed instead of copied. MAX_TAGS is public and unchanged.
- cadcraft-io: errors from the DXF converted from a DWG say so.
On the fuzzed file: before, 76 s and 13.4 GB, then the process aborted copying
the 11 GB text (under a 16 GB memory limit). After, 15 s and 5.3 GB, with
"DWG: converting this 0.2 MB file produced more than 1024 MB of drawing data
(the limit); ...". What's left is acadrust's reader itself (8 s, 5.3 GB on that
file), which this bridge can't bound without patching the crate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Move tests away from other PRs' hunks to avoid merge conflicts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* DXF: write non-ASCII text as \U+ escapes so AC1015 files stay valid (#164)
The writer declares $ACADVER AC1015 (R2000) and $DWGCODEPAGE ANSI_1252, where
text is in the code page, but wrote strings as raw UTF-8. Every other reader
decoded those bytes as CP1252 and turned non-ASCII text into mojibake; only
CADCraft (which tries UTF-8 first) read its own files back correctly.
- cadcraft_dxf::write_ascii now writes pure ASCII: every non-ASCII character
in a string group becomes the pre-R2007 \U+XXXX escape (UTF-16 code units,
so characters above U+FFFF are a surrogate pair of escapes). This covers
TEXT, MTEXT, ATTRIB/ATTDEF, table, block and layer names, xdata and
XRECORD strings alike. The header and the R2000 structure are unchanged,
so the DWG bridge (acadrust, which decodes the escapes) behaves as before.
- The reader combines surrogate-pair escapes, requires four hex digits, keeps
malformed escapes and unpaired surrogates as literal text, and now also
unescapes strings in binary DXF.
- Tests: R2000 save/reopen of CJK, Latin-1 and astral text in TEXT, MTEXT, a
layer name, a block name and ATTRIB/ATTDEF; pure-ASCII output with the
AC1015/ANSI_1252 header; UTF-8 (AC1032) and code-page (AC1015) input still
read; DWG round trip; hostile escapes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Move code and tests away from other PRs' hunks to avoid merge conflicts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>