Skip to content

Scalar interval block: unbounded value causes main-thread hang (missing magnitude validation) #8247

Description

@bhuvan-somisetty

Description

The scalar interval (+/-) block (Intervals palette) validates its argument's type but never its magnitude.

ScalarIntervalBlock.flow() in js/blocks/IntervalsBlocks.js:

flow(args, logo, turtle, blk) {
    if (args[1] === undefined) return;

    Singer.IntervalsActions.setScalarInterval(args[0], turtle, blk);

    return [args[1], 1];
}

passes args[0] straight through to setScalarInterval() (js/turtleactions/IntervalsActions.js:383), which only checks that the value is non-null and a number:

static setScalarInterval(value, turtle, blk) {
    let arg = value;
    if (arg === null || typeof arg !== "number") {
        activity.errorMsg(NOINPUTERRORMSG, blk);
        arg = 1;
    }
    ...
    const i = arg > 0 ? Math.floor(arg) : Math.ceil(arg);
    tur.singer.intervals.push(i);
    ...
}

No upper/lower bound is applied before the value is pushed onto tur.singer.intervals.

That value is then read back in GetNotesForInterval() (js/utils/musicutils.js:5320):

if (intervals && intervals.length) {
    octave = Math.floor(intervals[0] / 7);
}

and consumed by a synchronous loop in GetIntervalNumber() (js/turtleactions/IntervalsActions.js:116-119):

while (octave > 0) {
    totalIntervals += temperamentLength;
    octave--;
}

octave scales linearly with the raw scalar-interval value, so a single large (but finite) input drives this loop for however many iterations that implies — with no error message and no way to recover short of a forced tab close.

GetIntervalNumber() is reached synchronously and inline: it's called directly from the interval number and current interval reporter blocks' arg() methods (js/blocks/IntervalsBlocks.js), which are evaluated during flow, not scheduled/queued.

Expected Behavior

Either the block clamps/rejects out-of-range values with a clear error message (similar to how the Arc block's angle/radius arguments are bound-checked), or the underlying loop is otherwise protected from an unbounded iteration count.

Screenshots

N/A — this is a hang/freeze, not a visual defect.

How to Reproduce

  1. Add a "scalar interval (+/-)" block with a large numeric input (e.g. 999999999).
  2. Nest an "interval number" (or "current interval") reporter block inside it, feeding a print block.
  3. Run the project.

Console log Errors

None — the tab freezes silently; no error is logged or shown to the user.

Environment

  • Operating System: Windows
  • Browser (if applicable): N/A (reproducible in any browser)
  • Version of Software/Project: current master

Checklist

  • I have read and followed the project's code of conduct.
  • I have searched for similar issues before creating this one.
  • I have provided all the necessary information to understand and reproduce the issue.
  • I am willing to contribute to the resolution of this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions