Skip to content

Audit public mutable array state and ownership semantics #73

@0xC000005

Description

@0xC000005

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

  1. 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.
  2. Add regression tests showing that external mutation cannot corrupt:
    • evaluation,
    • binary/JSON save/load,
    • algebra compatibility,
    • TT rank/domain metadata,
    • spline knot routing.
  3. Update docs to explain ownership/copy semantics.
  4. 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.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions