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:
co-authored by
Claude Opus 5
parent
2ee18727cd
commit
4d246b17b8
@@ -200,6 +200,35 @@ def test_unknown_preset_is_refused():
|
||||
resolve_dimstyle("iso-25", [("DIMTXT", 2.5)])
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"separator",
|
||||
["\n", "\t", "\x00", "\x7f", chr(0x1F600), chr(0x8000), chr(0xFFFF)],
|
||||
ids=["newline", "tab", "nul", "del", "non-bmp", "first-above-signed-short", "u-ffff"],
|
||||
)
|
||||
def test_dimdsep_refuses_what_a_dxf_character_code_cannot_hold(separator):
|
||||
"""DIMDSEP is the one variable stored as a character code (group 278, a
|
||||
16-bit value); ``len == 1`` alone let these through, and the headless
|
||||
engine then wrote ``ord()`` unguarded — measured: ``'\\n'`` split the
|
||||
dimension text over two lines, NUL read back as a comma, and the emoji
|
||||
reached the file as 128512, which AutoCAD refuses as "not a single
|
||||
character". ezdxf's audit reports none of it."""
|
||||
with pytest.raises(ValueError, match="DIMDSEP"):
|
||||
check_dim_value("DIMDSEP", separator)
|
||||
with pytest.raises(ValueError, match="DIMDSEP"):
|
||||
resolve_dimstyle("iso-25", {"DIMDSEP": separator})
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"separator",
|
||||
[",", ".", " ", chr(0xB7), chr(0x66B), chr(0x7FFF)],
|
||||
ids=["comma", "point", "space", "middle-dot", "arabic-decimal", "last-signed-short"],
|
||||
)
|
||||
def test_dimdsep_takes_any_printable_separator_a_dxf_can_hold(separator):
|
||||
"""The comma, the point, the middle dot, the Arabic decimal separator, and
|
||||
the last code a signed short holds all pass; the guard is not an ASCII gate."""
|
||||
assert check_dim_value("DIMDSEP", separator) == separator
|
||||
|
||||
|
||||
def test_validate_overrides_alone_is_what_modify_uses():
|
||||
assert validate_overrides(None) == {}
|
||||
assert validate_overrides({"dimgap": -1}) == {"DIMGAP": -1.0}, "negative gap boxes the text"
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user