fix(task-9): DIMDSEP refuses control characters and code points above the 16-bit DXF group

check_dim_value's char branch only checked len == 1, so '\n', '\t', '\x00'
and non-BMP characters passed and the headless writer stored ord(value)
unguarded: '\n' split the dimension text over two lines, NUL read back as a
comma, and U+1F600 reached $DIMDSEP / group 278 as 128512, outside the 16-bit
range and refused by AutoCAD as "not a single character". ezdxf's audit
caught none of it. The same hole 827719f closed for names and fonts, left
open for the one variable stored as a character code.

The gate now refuses code < 32, DEL, and code > DIMDSEP_MAX_CODE (0x7FFF,
the signed short DWG stores) with a ValueError naming DIMDSEP, so nothing
reaches a backend. Pinned by a parametrized refusal test (newline, tab, NUL,
DEL, U+1F600, U+8000, U+FFFF), a positive test that the middle dot, the
Arabic decimal separator and U+7FFF still pass, and the ezdxf refusal test
now proves dimstyle_create / dimstyle_modify write nothing for these.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
Umut CAN
2026-09-17 14:52:57 +03:00
co-authored by Claude Opus 5
parent 2ee18727cd
commit 4d246b17b8
3 changed files with 63 additions and 3 deletions
+8
View File
@@ -134,6 +134,14 @@ async def test_refusals_happen_before_anything_is_written(backend):
with pytest.raises(ValueError, match="does not exist"):
await backend.dimstyle_set_current("NOPE")
assert backend._doc.dimstyles.get("ISO-25").dxf.dimdec == 2
# DIMDSEP is stored as ``ord(value)``: a control character or a code point
# above the 16-bit group 278 must stop here, not reach the table.
with pytest.raises(ValueError, match="DIMDSEP"):
await backend.dimstyle_create("Z", {"DIMDSEP": "\n"})
assert not backend._doc.dimstyles.has_entry("Z")
with pytest.raises(ValueError, match="DIMDSEP"):
await backend.dimstyle_modify("ISO-25", {"DIMDSEP": "\U0001f600"})
assert backend._doc.dimstyles.get("ISO-25").dxf.dimdsep == 44
async def test_builtin_arrowheads_render_save_and_report_one_spelling(backend, tmp_path):