This is an automated email from the ASF dual-hosted git repository.

ryankert01 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/mahout.git


The following commit(s) were added to refs/heads/main by this push:
     new ac30a8c95 fix(qdp): guard batch size multiplication against overflow 
(#1324)
ac30a8c95 is described below

commit ac30a8c954f692f0e57e53cef185497b68b61217
Author: KUAN-HAO HUANG <[email protected]>
AuthorDate: Mon May 18 19:49:33 2026 +0800

    fix(qdp): guard batch size multiplication against overflow (#1324)
    
    `Preprocessor::validate_batch` and `AmplitudeEncoder::encode_batch_f32`
    computed `num_samples * sample_size` without overflow checks, while the
    analogous angle encoder paths already use `checked_mul`. On 64-bit hosts
    the product can wrap and let an undersized buffer pass validation,
    leading to out-of-bounds reads in the encoder.
    
    Mirror the angle.rs pattern: use `checked_mul` and surface an
    `InvalidInput` error on overflow. Add a unit test covering the
    overflow path through the shared preprocessor.
---
 qdp/qdp-core/src/gpu/encodings/amplitude.rs | 10 ++++++++--
 qdp/qdp-core/src/preprocessing.rs           | 30 ++++++++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/qdp/qdp-core/src/gpu/encodings/amplitude.rs 
b/qdp/qdp-core/src/gpu/encodings/amplitude.rs
index e3081b65d..67d9f06ac 100644
--- a/qdp/qdp-core/src/gpu/encodings/amplitude.rs
+++ b/qdp/qdp-core/src/gpu/encodings/amplitude.rs
@@ -482,12 +482,18 @@ impl QuantumEncoder for AmplitudeEncoder {
                 sample_size, state_len, num_qubits
             )));
         }
-        if batch_data.len() != num_samples * sample_size {
+        let expected_len = num_samples.checked_mul(sample_size).ok_or_else(|| {
+            MahoutError::InvalidInput(format!(
+                "Batch size overflow: num_samples {} * sample_size {}",
+                num_samples, sample_size
+            ))
+        })?;
+        if batch_data.len() != expected_len {
             return Err(MahoutError::InvalidInput(format!(
                 "batch_data length mismatch (expected {} * {} = {}, got {})",
                 num_samples,
                 sample_size,
-                num_samples * sample_size,
+                expected_len,
                 batch_data.len()
             )));
         }
diff --git a/qdp/qdp-core/src/preprocessing.rs 
b/qdp/qdp-core/src/preprocessing.rs
index c8469aa39..625c9fa59 100644
--- a/qdp/qdp-core/src/preprocessing.rs
+++ b/qdp/qdp-core/src/preprocessing.rs
@@ -98,7 +98,13 @@ impl Preprocessor {
             ));
         }
 
-        if batch_data.len() != num_samples * sample_size {
+        let expected_len = num_samples.checked_mul(sample_size).ok_or_else(|| {
+            MahoutError::InvalidInput(format!(
+                "Batch size overflow: num_samples {} * sample_size {}",
+                num_samples, sample_size
+            ))
+        })?;
+        if batch_data.len() != expected_len {
             return Err(MahoutError::InvalidInput(format!(
                 "Batch data length {} doesn't match num_samples {} * 
sample_size {}",
                 batch_data.len(),
@@ -160,3 +166,25 @@ impl Preprocessor {
             .collect()
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn validate_batch_rejects_size_overflow() {
+        let data = [0.0_f64; 4];
+        let err = Preprocessor::validate_batch(&data, usize::MAX, 2, 1)
+            .expect_err("expected overflow error");
+        match err {
+            MahoutError::InvalidInput(msg) => {
+                assert!(
+                    msg.contains("overflow"),
+                    "unexpected error message: {}",
+                    msg
+                );
+            }
+            other => panic!("expected InvalidInput, got {:?}", other),
+        }
+    }
+}

Reply via email to