Repository: nushell/nushell (language: rust)

Issue:
Invalid pointer arithmetic
### Describe the bug

Nushell 0.102.0 fails to compile on 32-bit targets because it uses invalid pointer arithmetic.

https://github.com/nushell/nushell/blob/1aa2ed1947a0b891398558fcf4e4289849cc5a1d/crates/nu-command/src/conversions/into/duration.rs#L173-L185

Since it deals with pointers, it should use wrapping arithmetic, like [`subslice_range`](https://doc.rust-lang.org/std/primitive.slice.html#method.subslice_range) [does](https://doc.rust-lang.org/src/core/slice/mod.rs.html#4647-4666).

### How to reproduce

https://gitlab.alpinelinux.org/nibon7/aports/-/jobs/1718350

### Expected behavior

No panics.

### Configuration

0.102.0.  The build failed in CI, but it should be the usual Alpine configuration: `x86_64-alpine-linux-musl` target, 1.83.0 rustc/cargo.


Discussion / hints:

Fix patch:
diff --git a/crates/nu-command/src/conversions/into/duration.rs b/crates/nu-command/src/conversions/into/duration.rs
index d11cfeffc2c6f..3d11b83afb74d 100644
--- a/crates/nu-command/src/conversions/into/duration.rs
+++ b/crates/nu-command/src/conversions/into/duration.rs
@@ -170,16 +170,20 @@ fn into_duration(
     )
 }
 
-// convert string list of duration values to duration NS.
-// technique for getting substrings and span based on: https://stackoverflow.com/a/67098851/2036651
-#[inline]
-fn addr_of(s: &str) -> usize {
-    s.as_ptr() as usize
-}
-
 fn split_whitespace_indices(s: &str, span: Span) -> impl Iterator<Item = (&str, Span)> {
     s.split_whitespace().map(move |sub| {
-        let start_offset = span.start + addr_of(sub) - addr_of(s);
+        // Gets the offset of the `sub` substring inside the string `s`.
+        // `wrapping_` operations are necessary because the pointers can
+        // overflow on 32-bit platforms.  The result will not overflow, because
+        // `sub` is within `s`, and the end of `s` has to be a valid memory
+        // address.
+        //
+        // XXX: this should be replaced with `str::substr_range` from the
+        // standard library when it's stabilized.
+        let start_offset = span
+            .start
+            .wrapping_add(sub.as_ptr() as usize)
+            .wrapping_sub(s.as_ptr() as usize);
         (sub, Span::new(start_offset, start_offset + sub.len()))
     })
 }


Test patch: