Summary
Several public properties expose mutable array instances from core interpolants:
ChebyshevApproximation.Domain, NNodes, NodeArrays, TensorValues, Weights, DiffMatrices
ChebyshevSpline.Domain, NNodes, Knots
ChebyshevSlider.Domain, NNodes, Partition, PivotPoint
ChebyshevTT.Domain, NNodes
- record wrappers such as
Domain(double[][] Bounds), Ns(int[] Counts), and SpecialPoints(double[][] Points)
Because arrays are mutable even when the property setter is internal or absent, callers can corrupt object invariants after construction. Examples include mutating a built object's domain bounds to NaN, changing NNodes away from tensor shape, or changing stored tensor values before evaluation or serialization.
Why this is architectural
This should not be fixed as a small one-off validation patch. Binary write-side validation can prevent one malformed output path, but the same mutated state can affect JSON save, evaluation, algebra compatibility, roots/min/max, integration, and diagnostics.
Microsoft CA1819 explicitly warns that array-returning properties are not write-protected and says keeping an array tamper-proof requires returning a copy or changing the API shape. Microsoft also marks this as a breaking fix, which means it should be planned as a versioned public API hardening change rather than bundled into unrelated bug PRs.
References:
Proposed direction
- Decide the public contract:
- Snapshot APIs: properties return cloned arrays or read-only views; mutation requires explicit methods.
- Performance APIs: keep raw-array access but clearly mark as advanced/unsafe and add safe getters for normal users.
- Hybrid: keep current properties for compatibility in a minor release, add safe clone/read-only accessors, obsolete mutable properties, then remove/change in the next major version.
- Add regression tests showing that external mutation cannot corrupt:
- evaluation,
- binary/JSON save/load,
- algebra compatibility,
- TT rank/domain metadata,
- spline knot routing.
- Update docs to explain ownership/copy semantics.
- Audit DTO/serialization-state classes separately; returning arrays from internal DTOs may be acceptable, but public runtime objects should not expose mutable invariant storage accidentally.
Audit context
This was found while auditing .pcb binary load/save boundaries after PR #72. PR #72 intentionally remains narrow: it hardens read-side parsing of untrusted binary payloads and does not attempt a broad public API redesign.
Summary
Several public properties expose mutable array instances from core interpolants:
ChebyshevApproximation.Domain,NNodes,NodeArrays,TensorValues,Weights,DiffMatricesChebyshevSpline.Domain,NNodes,KnotsChebyshevSlider.Domain,NNodes,Partition,PivotPointChebyshevTT.Domain,NNodesDomain(double[][] Bounds),Ns(int[] Counts), andSpecialPoints(double[][] Points)Because arrays are mutable even when the property setter is internal or absent, callers can corrupt object invariants after construction. Examples include mutating a built object's domain bounds to
NaN, changingNNodesaway from tensor shape, or changing stored tensor values before evaluation or serialization.Why this is architectural
This should not be fixed as a small one-off validation patch. Binary write-side validation can prevent one malformed output path, but the same mutated state can affect JSON save, evaluation, algebra compatibility, roots/min/max, integration, and diagnostics.
Microsoft CA1819 explicitly warns that array-returning properties are not write-protected and says keeping an array tamper-proof requires returning a copy or changing the API shape. Microsoft also marks this as a breaking fix, which means it should be planned as a versioned public API hardening change rather than bundled into unrelated bug PRs.
References:
Proposed direction
Audit context
This was found while auditing
.pcbbinary load/save boundaries after PR #72. PR #72 intentionally remains narrow: it hardens read-side parsing of untrusted binary payloads and does not attempt a broad public API redesign.