Skip to content

Commit aaf890b

Browse files
authored
Merge pull request #346 from PyO3/release-0.17
merge 0.17 fixes into main
2 parents df4613e + 95e3bb5 commit aaf890b

File tree

6 files changed

+60
-17
lines changed

6 files changed

+60
-17
lines changed

.github/workflows/ci.yml

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
lint:
1717
runs-on: ubuntu-latest
1818
steps:
19-
- uses: actions/checkout@v2
19+
- uses: actions/checkout@v3
2020
- uses: actions-rs/toolchain@v1
2121
with:
2222
toolchain: stable
@@ -48,7 +48,7 @@ jobs:
4848
- python-version: pypy-3.8
4949
platform: { os: "ubuntu-latest", python-architecture: "x64", rust-target: "x86_64-unknown-linux-gnu" }
5050
steps:
51-
- uses: actions/checkout@v2
51+
- uses: actions/checkout@v3
5252
- name: Set up Python ${{ matrix.python-version }}
5353
uses: actions/setup-python@v2
5454
with:
@@ -90,17 +90,37 @@ jobs:
9090
runs-on: ubuntu-latest
9191
needs: [lint, check-msrv, examples]
9292
steps:
93-
- uses: actions/checkout@v2
93+
- uses: actions/checkout@v3
9494
- uses: messense/maturin-action@v1
9595
with:
9696
target: aarch64
9797
manylinux: auto
9898
args: --manifest-path examples/simple/Cargo.toml
9999

100+
address-sanitizer:
101+
runs-on: ubuntu-22.04
102+
needs: [lint, check-msrv, examples]
103+
steps:
104+
- uses: actions/checkout@v3
105+
- uses: actions-rs/toolchain@v1
106+
with:
107+
toolchain: nightly
108+
profile: minimal
109+
components: rust-src
110+
default: true
111+
- uses: Swatinem/rust-cache@v2
112+
continue-on-error: true
113+
- run: |
114+
pip install numpy
115+
cargo test -Zbuild-std --target x86_64-unknown-linux-gnu --release --lib --tests
116+
env:
117+
RUSTFLAGS: -Zsanitizer=address
118+
ASAN_OPTIONS: detect_leaks=0
119+
100120
check-msrv:
101121
runs-on: ubuntu-latest
102122
steps:
103-
- uses: actions/checkout@v2
123+
- uses: actions/checkout@v3
104124
- name: Set up Python
105125
uses: actions/setup-python@v2
106126
with:
@@ -152,7 +172,7 @@ jobs:
152172
examples:
153173
runs-on: ubuntu-latest
154174
steps:
155-
- uses: actions/checkout@v2
175+
- uses: actions/checkout@v3
156176
- name: Set up Python
157177
uses: actions/setup-python@v2
158178
with:
@@ -177,7 +197,7 @@ jobs:
177197
runs-on: ubuntu-latest
178198
needs: [lint, check-msrv, examples]
179199
steps:
180-
- uses: actions/checkout@v2
200+
- uses: actions/checkout@v3
181201
- name: Set up Python
182202
uses: actions/setup-python@v2
183203
with:

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
- Unreleased
44
- Drop our wrapper for NumPy iterators which were deprecated in v0.16.0 as ndarray's iteration facilities are almost always preferable. ([#324](https://github.com/PyO3/rust-numpy/pull/324))
55

6+
- v0.17.1
7+
- Fix use-after-free in `PyArray::resize`, `PyArray::reshape` and `PyArray::reshape_with_order`. ([#341](https://github.com/PyO3/rust-numpy/pull/341))
8+
- Fix UB in `ToNpyDims::as_dims_ptr` with dimensions of dynamic size (-1). ([#344](https://github.com/PyO3/rust-numpy/pull/344))
9+
610
- v0.17.0
711
- Add dynamic borrow checking to safely construct references into the interior of NumPy arrays. ([#274](https://github.com/PyO3/rust-numpy/pull/274))
812
- The deprecated iterator builders `NpySingleIterBuilder::{readonly,readwrite}` and `NpyMultiIterBuilder::add_{readonly,readwrite}` now take referencces to `PyReadonlyArray` and `PyReadwriteArray` instead of consuming them.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "numpy"
3-
version = "0.17.0"
3+
version = "0.17.1"
44
authors = [
55
"The rust-numpy Project Developers",
66
"PyO3 Project and Contributors <https://github.com/PyO3>"

src/array.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
464464
where
465465
ID: IntoDimension<Dim = D>,
466466
{
467-
let dims = dims.into_dimension();
467+
let mut dims = dims.into_dimension();
468468
let ptr = PY_ARRAY_API.PyArray_NewFromDescr(
469469
py,
470470
PY_ARRAY_API.get_type_object(py, npyffi::NpyTypes::PyArray_Type),
@@ -490,7 +490,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
490490
where
491491
ID: IntoDimension<Dim = D>,
492492
{
493-
let dims = dims.into_dimension();
493+
let mut dims = dims.into_dimension();
494494
let ptr = PY_ARRAY_API.PyArray_NewFromDescr(
495495
py,
496496
PY_ARRAY_API.get_type_object(py, npyffi::NpyTypes::PyArray_Type),
@@ -612,7 +612,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
612612
where
613613
ID: IntoDimension<Dim = D>,
614614
{
615-
let dims = dims.into_dimension();
615+
let mut dims = dims.into_dimension();
616616
unsafe {
617617
let ptr = PY_ARRAY_API.PyArray_Zeros(
618618
py,
@@ -1379,7 +1379,8 @@ impl<T: Element, D> PyArray<T, D> {
13791379
dims: ID,
13801380
order: NPY_ORDER,
13811381
) -> PyResult<&'py PyArray<T, ID::Dim>> {
1382-
let mut dims = dims.into_dimension().to_npy_dims();
1382+
let mut dims = dims.into_dimension();
1383+
let mut dims = dims.to_npy_dims();
13831384
let ptr = unsafe {
13841385
PY_ARRAY_API.PyArray_Newshape(
13851386
self.py(),
@@ -1436,7 +1437,8 @@ impl<T: Element, D> PyArray<T, D> {
14361437
/// [ndarray-resize]: https://numpy.org/doc/stable/reference/generated/numpy.ndarray.resize.html
14371438
/// [PyArray_Resize]: https://numpy.org/doc/stable/reference/c-api/array.html#c.PyArray_Resize
14381439
pub unsafe fn resize<ID: IntoDimension>(&self, dims: ID) -> PyResult<()> {
1439-
let mut dims = dims.into_dimension().to_npy_dims();
1440+
let mut dims = dims.into_dimension();
1441+
let mut dims = dims.to_npy_dims();
14401442
let res = PY_ARRAY_API.PyArray_Resize(
14411443
self.py(),
14421444
self.as_array_ptr(),

src/convert.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,11 @@ pub trait ToNpyDims: Dimension + Sealed {
213213
self.ndim() as c_int
214214
}
215215
#[doc(hidden)]
216-
fn as_dims_ptr(&self) -> *mut npyffi::npy_intp {
217-
self.slice().as_ptr() as *mut npyffi::npy_intp
216+
fn as_dims_ptr(&mut self) -> *mut npyffi::npy_intp {
217+
self.slice_mut().as_ptr() as *mut npyffi::npy_intp
218218
}
219219
#[doc(hidden)]
220-
fn to_npy_dims(&self) -> npyffi::PyArray_Dims {
220+
fn to_npy_dims(&mut self) -> npyffi::PyArray_Dims {
221221
npyffi::PyArray_Dims {
222222
ptr: self.as_dims_ptr(),
223223
len: self.ndim_cint(),

tests/array.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::mem::size_of;
44
use half::f16;
55
use ndarray::{array, s, Array1, Dim};
66
use numpy::{
7-
dtype, get_array_module, pyarray, PyArray, PyArray1, PyArray2, PyArrayDescr, PyArrayDyn,
8-
ToPyArray,
7+
dtype, get_array_module, npyffi::NPY_ORDER, pyarray, PyArray, PyArray1, PyArray2, PyArrayDescr,
8+
PyArrayDyn, ToPyArray,
99
};
1010
use pyo3::{
1111
py_run, pyclass, pymethods,
@@ -508,6 +508,23 @@ fn get_works() {
508508
});
509509
}
510510

511+
#[test]
512+
fn reshape() {
513+
Python::with_gil(|py| {
514+
let array = PyArray::from_iter(py, 0..9)
515+
.reshape_with_order([3, 3], NPY_ORDER::NPY_FORTRANORDER)
516+
.unwrap();
517+
518+
assert_eq!(
519+
array.readonly().as_array(),
520+
array![[0, 3, 6], [1, 4, 7], [2, 5, 8]]
521+
);
522+
assert!(array.is_fortran_contiguous());
523+
524+
assert!(array.reshape([5]).is_err());
525+
});
526+
}
527+
511528
#[cfg(feature = "half")]
512529
#[test]
513530
fn half_works() {

0 commit comments

Comments
 (0)