You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Safe code could construct a Matrix whose data.len() disagrees with
row * col by writing the public fields directly, and the internal
unsafe code (raw pointers via ptr(), matrixmultiply / BLAS dgemm
calls, Index arithmetic) trusts those fields without checking the
buffer length, so heap out-of-bounds reads and writes were reachable
without any unsafe in user code (reported in #101 for peroxide
0.41.0).
Root fix, targeted at v0.42.0 (breaking change):
* Matrix and ComplexMatrix fields are now pub(crate); the invariant
data.len() == row * col can no longer be broken from outside the
crate.
* The matrix() / cmatrix() constructors assert the invariant, so the
remaining public construction path is validated.
* New public accessors replace direct field reads: nrow(), ncol(),
layout() (storage order), into_vec() (consume into the buffer).
Reading the buffer stays available through as_slice() /
as_mut_slice(); dimensions also via MatrixTrait::shape().
* cbind! / rbind! expanded to field accesses at the caller's site and
would no longer compile for downstream users; rewritten with the
public accessors.
* Struct-literal doc examples replaced with constructor calls; tests
and examples migrated.
Known follow-up: serde / rkyv deserialization can still bypass the
constructor validation; tracked separately.
Migration for downstream code:
m.row -> m.nrow()
m.col -> m.ncol()
m.shape -> m.layout()
m.data -> m.as_slice() / as_mut_slice() / into_vec()
Matrix { .. } literal -> matrix(data, row, col, shape)
0 commit comments