Skip to content

BotMaker collection functions crash on edge cases: missing validation for empty lists and invalid indices #58

Description

@vishalsingh2972

Problem

Three collection functions in BotMaker lack input validation and crash on edge cases rather than
failing gracefully:

  1. First() crashes on empty lists → IndexOutOfBoundsException
  2. FirstN() lacks negative index check → May create invalid subLists
  3. Slice() doesn't validate beginIndex < endIndex → IllegalArgumentException

These are core utility functions used in rule logic and visibility filtering. Uncaught exceptions
break the entire evaluation pipeline.

Current State

First.java (lines 48-50)

public Object apply(Context<Runtime> context, List<Object> list) {
    return list.get(0);  // ❌ Crashes if list.isEmpty()
}

Error: IndexOutOfBoundsException if called with empty list.

FirstN.java (lines 56-58)

public Object apply(Context<Runtime> context, List<Object> list, Long n) {
    return list.subList(0, Math.min(n.intValue(), list.size()));
    // ❌ No validation: n could be negative, causing IllegalArgumentException
}

Error: IllegalArgumentException if n < 0 (subList requires non-negative indices).

Slice.java (lines 74-80)

protected Object apply(
    Context<Runtime> context, Object input, Long beginIndex, Long endIndex) {
    if (input instanceof String) {
        return ((String) input).substring(beginIndex.intValue(), endIndex.intValue());
        // ❌ No check: what if beginIndex > endIndex?
    }
    // ...
}

Error: StringIndexOutOfBoundsException or IllegalArgumentException if indices are invalid.

Impact

  • Visibility filtering breaks when rules call these functions with malformed inputs
  • Silent rule failure — exceptions propagate instead of being handled gracefully
  • Unpredictable behavior — different errors for different collections

Proposed Solution

  1. First(): Validate non-empty list or return null/default

    public Object apply(Context<Runtime> context, List<Object> list) {
        if (list.isEmpty()) {
            throw new IllegalArgumentException("First() called on empty list");
        }
        return list.get(0);
    }
  2. FirstN(): Validate n >= 0

    public Object apply(Context<Runtime> context, List<Object> list, Long n) {
        long count = Math.max(0, n);  // or throw if n < 0
        return list.subList(0, (int) Math.min(count, list.size()));
    }
  3. Slice(): Validate indices before use

    protected Object apply(Context<Runtime> context, Object input, Long begin, Long end) {
        if (begin < 0 || end < 0 || begin > end) {
            throw new IllegalArgumentException(
                String.format("Invalid slice indices: begin=%d, end=%d", begin, end)
            );
        }
        // ...
    }

References

  • botmaker/src/java/com/twitter/botmaker/function/collection/First.java (line 49)
  • botmaker/src/java/com/twitter/botmaker/function/collection/FirstN.java (line 57)
  • botmaker/src/java/com/twitter/botmaker/function/collection/Slice.java (lines 74-80)

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