From b953fe5b16c2e5a21c47cb05b384057b0e30f463 Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Wed, 12 Dec 2018 19:45:51 -0500 Subject: [PATCH 1/2] Specialize do_slice for |step| = 1 case --- src/dimension/mod.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/dimension/mod.rs b/src/dimension/mod.rs index 9a7f5dadb..310695df6 100644 --- a/src/dimension/mod.rs +++ b/src/dimension/mod.rs @@ -380,15 +380,18 @@ pub fn do_slice(dim: &mut usize, stride: &mut usize, slice: Slice) -> isize { offset += stride_offset(m - 1, *stride); } - let s_prim = s * step; - - let d = m / step.abs() as usize; - let r = m % step.abs() as usize; - let m_prim = d + if r > 0 { 1 } else { 0 }; + // Update dimension. + let abs_step = step.abs() as usize; + *dim = if abs_step == 1 { + m + } else { + let d = m / abs_step; + let r = m % abs_step; + d + if r > 0 { 1 } else { 0 } + }; - // Update dimension and stride coordinate - *dim = m_prim; - *stride = s_prim as usize; + // Update stride. + *stride = (s * step) as usize; offset } From 358c8d9c06424d99e889137d954934a17d6966ff Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Wed, 12 Dec 2018 20:24:41 -0500 Subject: [PATCH 2/2] Prevent overflow when calculating slice stride For example, consider the case where the original axis length is `1`, the original stride is `2`, and `step` is `isize::MAX`. --- src/dimension/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dimension/mod.rs b/src/dimension/mod.rs index 310695df6..aebcfc662 100644 --- a/src/dimension/mod.rs +++ b/src/dimension/mod.rs @@ -390,8 +390,9 @@ pub fn do_slice(dim: &mut usize, stride: &mut usize, slice: Slice) -> isize { d + if r > 0 { 1 } else { 0 } }; - // Update stride. - *stride = (s * step) as usize; + // Update stride. The additional check is necessary to avoid possible + // overflow in the multiplication. + *stride = if *dim <= 1 { 0 } else { (s * step) as usize }; offset }