fix(task-4): refuse non-finite/non-numeric XDATA and budget 16 KB per entity
encode_values() let strings and nan/inf through float() into 1010 point
coordinates and never finiteness-checked bare 1040 reals, so
entity_set_xdata(handle, app, [["nan", 1]]) or [float("inf")] wrote a
literal "nan"/"inf" into the DXF (and every undo snapshot) and read back
as null. Numbers now go through the same rule block_specs._scalar applies:
int/float only, bool refused, math.isfinite, error naming values[i][j].
The advertised 16 KB limit was per call per app; AutoCAD's is per object
across every application (xdroom/xdsize), so three 15 KB apps on one
entity passed headless and would fail SetXData live. check_entity_budget()
now sums the entity's existing XDATA under every other app (ACAD's DSTYLE
overrides included) plus each 1001 marker with AutoCAD's resbuf sizes,
and both engines run it before registering the APPID or writing; removal
is never refused. The result's "bytes" is that same accounting.
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
41d6d3505a
commit
f4c2f27bee
@@ -4540,7 +4540,12 @@ class EzdxfBackend(AutoCADBackend):
|
||||
return await self._async(_sync)
|
||||
|
||||
async def entity_set_xdata(self, handle, app_name, values) -> dict:
|
||||
from backends.xdata_specs import encode_values, validate_app_name
|
||||
from backends.xdata_specs import (
|
||||
app_size,
|
||||
check_entity_budget,
|
||||
encode_values,
|
||||
validate_app_name,
|
||||
)
|
||||
|
||||
# Validate and type every value before touching the document: a bad
|
||||
# values[i] raises here and nothing is written.
|
||||
@@ -4562,6 +4567,16 @@ class EzdxfBackend(AutoCADBackend):
|
||||
"removed": True,
|
||||
"backend": "ezdxf",
|
||||
}
|
||||
# The 16 KB limit is per entity across every application (ACAD's
|
||||
# own DSTYLE overrides included), so the gate sees what is already
|
||||
# there. Raises before the APPID is registered or anything is set.
|
||||
existing = {}
|
||||
if ent.xdata is not None:
|
||||
existing = {
|
||||
other: [(tag.code, tag.value) for tag in other_tags]
|
||||
for other, other_tags in ent.xdata.data.items()
|
||||
}
|
||||
check_entity_budget(app, tags, existing)
|
||||
if app not in doc.appids:
|
||||
doc.appids.add(app)
|
||||
ent.set_xdata(app, tags)
|
||||
@@ -4571,7 +4586,7 @@ class EzdxfBackend(AutoCADBackend):
|
||||
"handle": handle,
|
||||
"app_name": app,
|
||||
"value_count": len(tags),
|
||||
"bytes": sum(len(str(v)) for _, v in tags),
|
||||
"bytes": app_size(app, tags),
|
||||
"removed": False,
|
||||
"backend": "ezdxf",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user