Skip to content

Panic in format64_to_fixed when rounding carries past all integer digits #55

@Ansh-699

Description

@Ansh-699

Description

format64_to_fixed panics in debug builds (and has UB in release builds) when rounding causes a carry that propagates through all integer digits (e.g., 9.5 with toFixed(0) should produce "10").

Reproducer

Using Boa (which calls ryu_js::Buffer::format_to_fixed):

(9.5).toFixed(0)   // panics (expected: "10")
(99.5).toFixed(0)  // panics (expected: "100")

Panic

assertion failed: (0..self.len).contains(&i)
Location: ryu-js-1.0.2/src/pretty/to_fixed/mod.rs:225

Root Cause

In the rounding loop at the end of format64_to_fixed (line ~621), result.get(round_index) is called before checking round_index == -1:

round_index -= 1;
let c = result.get(round_index);        // reads buffer[-1] when round_index is -1
if round_index == -1 || c == b'-' {  // check happens AFTER the read

When all integer digits are 9, the carry turns each to 0 and round_index reaches -1. The next result.get(-1) is an out-of-bounds read.

Negative numbers are unaffected because '-' at index 0 stops the loop before round_index can underflow.

Fix

Move the boundary check before the read:

loop {
    round_index -= 1;
    if round_index == -1 {
        result.set(0, b'1');
        if dot_index > 0 {
            result.set(dot_index, b'0');
            result.set(dot_index + 1, b'.');
        }
        result.append_byte(b'0');
        break;
    }
    let c = result.get(round_index);
    if c == b'-' {
        result.set(round_index + 1, b'1');
        if dot_index > 0 {
            result.set(dot_index, b'0');
            result.set(dot_index + 1, b'.');
        }
        result.append_byte(b'0');
        break;
    }
    // ... rest unchanged
}

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