Repository: pola-rs/polars
File: crates/polars-arrow/src/mmap/array.rs (Rust)

Code before:
            is_aligned,
            "primitive type with size <= 8 bytes should have been aligned"
        );
        let bytes_ptr = bytes.as_ptr();

        unsafe {
            create_array(
                data,
                num_rows,
                null_count,
                [validity, Some(bytes_ptr)].into_iter(),
                [].into_iter(),
                None,
                None,
            )
        }
    } else {
        let mut values = vec![P::default(); num_rows];
        unsafe {
            std::ptr::copy_nonoverlapping(
                bytes.as_ptr(),
                values.as_mut_ptr() as *mut u8,
                bytes.len(),
            )
        };
        // Now we need to keep the new buffer alive
        let owned_data = Arc::new((
            // We can drop the original ref if we don't have a validity
            validity.and(Some(data)),
            values,
        ));
        let bytes_ptr = owned_data.1.as_ptr() as *mut u8;

        unsafe {
            create_array(
                owned_data,
                num_rows,
                null_count,
                [validity, Some(bytes_ptr)].into_iter(),
                [].into_iter(),
                None,
                None,
            )
        }
    };

    Ok(out)
}

#[allow(clippy::too_many_arguments)]
fn mmap_list<O: Offset, T: AsRef<[u8]>>(

Review comment (suggestion):
Ensure we copy based on allocated capacity rather than the source length

Expanding the diff above, `check_bytes_len_and_is_aligned` on L282 does only guarantees the source length is at least the required number of bytes; meaning that there could be more bytes.

https://github.com/pola-rs/polars/blob/88cd1b01a7f55d9bf85f243fd50d2ba6071199e0/crates/polars-arrow/src/mmap/array.rs#L38



Code after:
            is_aligned,
            "primitive type with size <= 8 bytes should have been aligned"
        );
        let bytes_ptr = bytes.as_ptr();

        unsafe {
            create_array(
                data,
                num_rows,
                null_count,
                [validity, Some(bytes_ptr)].into_iter(),
                [].into_iter(),
                None,
                None,
            )
        }
    } else {
        let mut values: Vec<P> = Vec::with_capacity(num_rows);
        let num_bytes = num_rows * std::mem::size_of::<P>();

        assert!(bytes.len() >= num_bytes);
        unsafe {
            std::ptr::copy_nonoverlapping(
                bytes.as_ptr(),
                values.as_mut_ptr() as *mut u8,
                num_bytes,
            );

            values.set_len(num_rows);
        };

        // Now we need to keep the new buffer alive
        let owned_data = Arc::new((
            // We can drop the original ref if we don't have a validity
            validity.and(Some(data)),
            values,
        ));
        let bytes_ptr = owned_data.1.as_ptr() as *mut u8;

        unsafe {
            create_array(
                owned_data,
                num_rows,
                null_count,
                [validity, Some(bytes_ptr)].into_iter(),
                [].into_iter(),
                None,
                None,
            )
        }
    };