Skip to content

Arithmetic overflow panic when scan limit is u32::MAX and buffer contains deleted entries #514

@c4pt0r

Description

@c4pt0r

Bug Description

When calling txn.scan(range, u32::MAX) within a transaction that has previously deleted entries, the code panics with:

thread 'tokio-runtime-worker' panicked at src/transaction/buffer.rs:133:31:
attempt to add with overflow

Root Cause

In src/transaction/buffer.rs line 133:

let redundant_limit = limit
    + mutation_range
        .clone()
        .filter(|(_, m)| matches!(m, BufferEntry::Del))
        .count() as u32;

When limit = u32::MAX and there are any deleted entries in the buffer, this addition overflows.

Reproduction Steps

  1. Begin a transaction
  2. Delete one or more rows
  3. Within the same transaction, call scan() with u32::MAX as the limit
  4. Panic occurs

Example:

let mut txn = client.begin_pessimistic().await?;
txn.delete(key).await?;
let pairs = txn.scan(range, u32::MAX).await?;  // PANIC!

Expected Behavior

Using u32::MAX as scan limit (meaning "scan all") should be a valid operation and not cause overflow.

Suggested Fix

Use saturating arithmetic:

let redundant_limit = limit.saturating_add(
    mutation_range
        .clone()
        .filter(|(_, m)| matches!(m, BufferEntry::Del))
        .count() as u32
);

Current Workaround

Use i32::MAX as u32 instead of u32::MAX as the scan limit to leave headroom for the addition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions